View Full Version : How to know my trasaction is successfully committed
floyd
08-14-2007, 04:28 PM
Hi all,
I use TransactionProxyFactoryObject and set PreInterceptor to do something before trasaction start. I know there is a PostInterceptor could be used, but how can I have indication that current trasaction was successfully committed in my Advice(Interceptor implementation)? What I actually need to do is insert a audit-trail record to database only when my trasaction successfully commit.
Do you have any idea?
Thanks!
Mark Pollack
08-14-2007, 09:03 PM
Hi Floyd,
You can create after returning advice that will execute only if the transactionaly advised method executes successfully
public class AuditTrailAdvice : IAfterReturningAdvice
{
private static readonly ILog LOG = LogManager.GetLogger(typeof(AuditTrailAdvice));
public void AfterReturning(object returnValue, MethodInfo method, object[] args, object target)
{
LOG.Info("Auditing the transaction....");
}
}
This maybe enough for you if you don't specify any rollback rules and essentially have the behavioral contract that no exception=commit. This breaks down if you specify rollback rules, i.e don't rollback on case of 'MyException'. After returning advice won't be called in this case, because 'MyException' is still thrown, but a commit will occur.
A more robust approach is to register a listener with
TransactionSynchronizationManager (http://www.springframework.net/docs/1.1-RC1/sdk/2.0/html/Spring.Data~Spring.Transaction.Support.Transaction SynchronizationManager.html). You would need to place this advice after the transaction advice, since you can only register a listener with the manager once a transaction has been started.
public class AuditingAdvice : IMethodInterceptor
{
private AuditingListener txListener;
public AuditingListener AuditingListener
{ set { txListener = value; } }
public object Invoke(IMethodInvocation invocation)
{
txListener.MethodInfo = invocation.Method;
txListener.Args = invocation.Arguments;
txListener.Target = invocation.Target;
TransactionSynchronizationManager.RegisterSynchron ization(txListener);
return invocation.Proceed();
}
}
and
public class AuditingListener : ITransactionSynchronization, IComparable
{
// simple properties not shown
public void AfterCompletion(TransactionSynchronizationStatus status)
{
switch(status)
{
case TransactionSynchronizationStatus.Committed:
LOG.Info("Auditing on Committed transaction for method " + methodInfo.Name);
break;
case TransactionSynchronizationStatus.Rolledback:
LOG.Info("Auditing on Rolledback transaction for method " + methodInfo.Name);
break;
case TransactionSynchronizationStatus.Unknown:
LOG.Info("Auditing on unknown transaction status status for method " + methodInfo.Name);
break;
}
}
// other methods not shown.
The implementation of the simple properties should store those values in thread local storage since this listener would be used for all transaction processing. Otherwise one could create a 'new AuditListener' in code, passing in the relevant parameters shown above, and calling IApplicationContext.ConfigureObject(object o, string name) to have spring wire up the rest, for example some db related properties. The registration of the listeners in the TransactionSynchronizatonManager already accounts for thread local storage of the listeners to notify.
You would then configure AuditingListener to write to the audit trail, preferably in some asynchronous manner to that the real tx processing isn't delayed due to auditing (if that meets your requirements.)
Cheers,
Mark
Mark Pollack
08-14-2007, 09:30 PM
Hi,
I just fixed a bug, instead of the ITransactionSynchronization implementation having to implement IComparable, you can instead implement Spring.Core.IOrdered, which is easier to implement as you only need to specify a number. Lower numbers having higher priority to be fired in the list of listeners. You could als not implement IOrdered, if you don't care about the ordering.
Cheers,
Mark
floyd
08-15-2007, 03:03 AM
Hi Mark,
Thanks for your detailed explanation.
I'll try your suggesstion today.
vBulletin® v3.7.3, Copyright ©2000-2008, Jelsoft Enterprises Ltd.