Using the TransactionTemplate
Write a TransactionCallback implementation that will contain all of the code that you need to have execute in the context of a transaction.
You will then pass an instance of your custom TransactionCallback to the execute(..) method exposed on the TransactionTemplate.
public class SimpleService implements Service {
// single TransactionTemplate shared amongst all methods in this instance
private final TransactionTemplate transactionTemplate;
// use constructor-injection to supply PlatformTransactionManager
public SimpleService(PlatformTransactionManager transactionManager) {
this.transactionTemplate =
new TransactionTemplate (transactionManager);
this.transactionTemplate.setIsolationLevel(
TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
this.transactionTemplate.setTimeout(30); // 30 seconds
}
public Object someServiceMethod() {
return transactionTemplate.execute(new TransactionCallback() {
// the code in this method executes in a transactional context
public Object doInTransaction(TransactionStatus status) {
updateOperation1();
return resultOfUpdateOperation2();
}
});
}
}
If there is no return value, use the convenient TransactionCallbackWithoutResult class via an anonymous class.
transactionTemplate.execute(new TransactionCallbackWithoutResult(){
protected void doInTransactionWithoutResult(TransactionStatus status) {
updateOperation1();
updateOperation2();
}
});
Code within the callback can roll the transaction back by calling the setRollbackOnly() method on the supplied TransactionStatus object.
transactionTemplate.execute(
new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
updateOperation1();
updateOperation2();
} catch (SomeBusinessExeption ex) {
status.setRollbackOnly();
}
}
});
Transaction settings such as the propagation mode, the isolation level, the timeout, and so forth can be set on the TransactionTemplate either programmatically or in configuration.
<bean id="sharedTransactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="isolationLevelName" value="ISOLATION_READ_UNCOMMITTED"/>
<property name="timeout" value="30"/>
</bean>
Instances of the TransactionTemplate class are threadsafe; so, in that instances do not maintain any conversational state.
If a class needed to use a TransactionTemplate with different settings (for example, a different isolation level), then two distinct TransactionTemplate instances would need to be created and used.
Using the PlatformTransactionManager
Simply pass the implementation of the PlatformTransactionManager you're using to your bean via a bean reference.
Then, using the TransactionDefinition and TransactionStatus objects you can initiate transactions, rollback and commit.
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can only be done programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
try {
// execute your business logic here
}
catch (MyException ex) {
txManager.rollback(status);
throw ex;
}
txManager.commit(status);
No comments:
Post a Comment
Note: only a member of this blog may post a comment.