应用的代码必须在一个事务性的上下文中执行,这样就会像这样一样显式的使用TransactionTemplate。你作为一个应用程序员, 会写一个 TransactionCallback 的实现, (通常会用匿名类来实现 )这样的实现会包含所以你需要在该事务上下文中执行的代码。 然后你会把一个你自己实现TransactionCallback的实例传递给TransactionTemplate暴露的execute(..) 方法。
- public class SimpleService implements Service {
- // single TransactionTemplate shared amongst all methods in this instance
- private final TransactionTemplate transactionTemplate;
- // use constructor-injection to supply the PlatformTransactionManager
- public SimpleService(PlatformTransactionManager transactionManager) {
- Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
- this.transactionTemplate = new TransactionTemplate(transactionManager);
- }
- 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();
- }
- });
- }
- }
public class SimpleService implements Service { // single TransactionTemplate shared amongst all methods in this instance private final TransactionTemplate transactionTemplate; // use constructor-injection to supply the PlatformTransactionManager public SimpleService(PlatformTransactionManager transactionManager) { Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null."); this.transactionTemplate = new TransactionTemplate(transactionManager); } 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(); } }); } }
如果不需要返回值,更方便的方式是创建一个 TransactionCallbackWithoutResult
的匿名类,如下:
transactionTemplate.execute(new () { protected void doInTransactionWithoutResult(TransactionStatus status) { updateOperation1(); updateOperation2(); } });
回调方法内的代码可以通过调用 TransactionStatus
对象的 setRollbackOnly()
方法来回滚事务。
诸如传播模式、隔离等级、超时等等的事务设置都可以在TransactionTemplate
中或者通过配置或者编程式地实现。 TransactionTemplate
实例默认继承了默认事务设置 。 下面有个编程式的为一个特定的TransactionTemplate
定制事务设置的例子。
- public class SimpleService implements Service {
- private final TransactionTemplate transactionTemplate;
- public SimpleService(PlatformTransactionManager transactionManager) {
- Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
- this.transactionTemplate = new TransactionTemplate(transactionManager);
- // the transaction settings can be set here explicitly if so desired
- this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
- this.transactionTemplate.setTimeout(30); // 30 seconds
- // and so forth...
- }
- }
public class SimpleService implements Service { private final TransactionTemplate transactionTemplate; public SimpleService(PlatformTransactionManager transactionManager) { Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null."); this.transactionTemplate = new TransactionTemplate(transactionManager); // the transaction settings can be set here explicitly if so desired this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED); this.transactionTemplate.setTimeout(30); // 30 seconds // and so forth... } }
在下面的例子中,我们将会演示如何使用Spring XML配置来定制TransactionTemplate
的事务属性。 sharedTransactionTemplate
可以被注入到所有需要的服务中去。
- "sharedTransactionTemplate"
- class="org.springframework.transaction.support.TransactionTemplate">
- "isolationLevelName" value="ISOLATION_READ_UNCOMMITTED"/>
- "timeout" value="30"/>
- "
"
最后,TransactionTemplate
类的实例是线程安全的,任何状态都不会被保存。 TransactionTemplate
实例 的确会 维护配置状态,所以当一些类选择共享一个单独的 TransactionTemplate
实例时, 如果一个类需要使用不同配置的TransactionTemplate
(比如,不同的隔离等级), 那就需要创建和使用两个不同的TransactionTemplate
。