2.2 指定事务设置
诸如传播模式、隔离等级、超时等等的事务设置都可以在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... } }
使用Spring XML配置来定制TransactionTemplate的事务属性。 sharedTransactionTemplate 可以被注入到所有需要的服务中去。
<bean id="sharedTransactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="isolationLevelName" value="ISOLATION_READ_UNCOMMITTED"/> <property name="timeout" value="30"/> </bean>"
TransactionTemplate 类的实例是线程安全的,任何状态都不会被保存。 TransactionTemplate 实例的确会维护配置状态,所以当一些类选择共享一个单独的 TransactionTemplate实例时,如果一个类需要使用不同配置的TransactionTemplate(比如,不同的隔离等级), 那就需要创建和使用两个不同的TransactionTemplate。
2.3 案例
@Test public void test1() throws Exception { //定义一个数据源 org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/mydb?characterEncoding=UTF-8"); dataSource.setUsername("root"); dataSource.setPassword("root123"); dataSource.setInitialSize(5); //定义一个JdbcTemplate,用来方便执行数据库增删改查 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); //1.定义事务管理器,给其指定一个数据源(可以把事务管理器想象为一个人,这个人来负责事务的控制操作) PlatformTransactionManager platformTransactionManager = new DataSourceTransactionManager(dataSource); //2.定义事务属性:TransactionDefinition,TransactionDefinition可以用来配置事务的属性信息,比如事务隔离级别、事务超时时间、事务传播方式、是否是只读事务等等。 DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition(); transactionDefinition.setTimeout(10);//如:设置超时时间10s //3.创建TransactionTemplate对象 TransactionTemplate transactionTemplate = new TransactionTemplate(platformTransactionManager, transactionDefinition); /** * 4.通过TransactionTemplate提供的方法执行业务操作 * 主要有2个方法: * (1).executeWithoutResult(Consumer action):没有返回值的,需传递一个Consumer对象,在accept方法中做业务操作 * (2). T execute(TransactionCallback action):有返回值的,需要传递一个TransactionCallback对象,在doInTransaction方法中做业务操作 * 调用execute方法或者executeWithoutResult方法执行完毕之后,事务管理器会自动提交事务或者回滚事务。 * 那么什么时候事务会回滚,有2种方式: * (1)transactionStatus.setRollbackOnly();将事务状态标注为回滚状态 * (2)execute方法或者executeWithoutResult方法内部抛出异常 * 什么时候事务会提交? * 方法没有异常 && 未调用过transactionStatus.setRollbackOnly(); */ transactionTemplate.executeWithoutResult(new Consumer() { @Override public void accept(TransactionStatus transactionStatus) { jdbcTemplate.update("insert into t_user (name) values (?)", "transactionTemplate-1"); jdbcTemplate.update("insert into t_user (name) values (?)", "transactionTemplate-2"); } }); System.out.println("after:" + jdbcTemplate.queryForList("SELECT * from t_user")); } output: after:[{id=1, name=transactionTemplate-1}, {id=2, name=transactionTemplate-2}]
executeWithoutResult:无返回值场景
executeWithoutResult(Consumer action):没有返回值的,需传递一个Consumer对象,在accept方法中做业务操作
/
transactionTemplate.executeWithoutResult(new Consumer() { @Override public void accept(TransactionStatus transactionStatus) { //执行业务操作 } });
execute:有返回值场景
T execute(TransactionCallback action):有返回值的,需要传递一个TransactionCallback对象,在doInTransaction方法中做业务操作