Jai’s Weblog – Tech, Security & Fun…

Tech, Security & Fun…

  • Jaibeer Malik

    Jaibeer Malik
  • View Jaibeer Malik's profile on LinkedIn
  • Subscribe

  • Feedburner

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 29 other followers

  • Archives

  • Categories

  • Stats

    • 379,210
  • Live Traffic

Handling semi-transactional cases in spring programmatically

Posted by Jai on June 7, 2008

Consider a case in which you are updating information in local database and need to publish the same information some where on the remote application over network. You don’t have control over the transactional behavior of the remote application but some how get to know that the publishing/operation is not successful.

There can be scenarios when the remote operation is successful but you local database update fails, in such a situation you must be aware of what reverse operation should be done on remote application to revert it. The following cases can arise in semi-transaction cases:

Local operation Remote Operation Transaction Behavior Remote App-State
Successful Failure Rollback Remote App will handle it
Failure Failure Rollback Remote App will handle it
Failure Successful Rollback Revert call to be send
Successful Successful Commit Successful

Now how to handle such kind of scenarios and reverse transaction programmatically. I will walk you through small example to handle it.

Interface ReverseTransactionCallback:

***************

public interface ReverseTransactionCallback {

void executeTransaction();

void executeReverseTransaction();

}
****************

This interface contains two methods to execute in transaction or if the transaction fails then this is called to rollback stuff on remote application.

Reverse Transaction Template – ReversableTransactionTemplate:

**************

public class ReversableTransactionTemplate {

private PlatformTransactionManager transactionManager;

protected void executeReverseTransactionCallback(ReverseTransactionCallback callback) {
TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionDefinition(
TransactionDefinition.PROPAGATION_REQUIRES_NEW));
try {
callback.executeTransaction();
} catch (RuntimeException ex) {
rollbackOnException(transaction, ex);
throw ex;
} catch (Error err) {
rollbackOnException(transaction, err);
throw err;
}
try {
transactionManager.commit(transaction);
} catch (TransactionException e) {
try {
callback.executeReverseTransaction();
} catch (RuntimeException ex) {
LOG.error(“Commit exception overridden by rollback exception”, e);
throw ex;
} catch (Error err) {
LOG.error(“Commit exception overridden by rollback exception”, e);
throw err;
}
throw e;
}
}

private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {
LOG.debug(“Initiating transaction rollback on application exception”, ex);
try {
this.transactionManager.rollback(status);
} catch (RuntimeException ex2) {
LOG.error(“Application exception overridden by rollback exception”, ex);
throw ex2;
} catch (Error err) {
LOG.error(“Application exception overridden by rollback error”, ex);
throw err;
}
}

…..

}
****************

This is the template which handles commit/rollback of the stuff using org.springframework.transaction.PlatformTransactionManager and does the exception handling also.

Local operation and remote operation Service – UpdateLocalDBAndPostToService:

********************

public class UpdateLocalDBAndPostToService extends ReversableTransactionTemplate {

public void doOperation() {
try {
executeReverseTransactionCallback(new ReverseTransactionCallback() {
public void executeTransaction() {
localOperationService.storeData(data);
httpPostClient.publishData(data);
}

public void executeReverseTransaction() {
httpPostClient.publishDataReverse(data);
}
});
} catch (Exception e) {
LOG.error(“Failed to update.”, e);
}
}

….

….

}

***************************

Look at the implementation of executeTransaction() method which will update local database and will publish to remote application. Lets go through each scenario in case of exception:

Local operation fails before commit: Local operation is done first, so in case of exception the rollback will be done on local side and no communication with remote app.

Local operation successful but Remote operation fails: the transaction is rolled back on local side.

Local operation successful and remote operation successful but the commit fails: the transaction is rolled back on local side and executeReverseTransaction() method is called for reversal command on remote application. This is the only scenario where we need to send reversal call to remote application.

All Successful : Enjoy…job is done. All well if it ends well.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: