Spring编程式事务详解(下)

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方法中做业务操作

Spring编程式事务详解(下)


/

transactionTemplate.executeWithoutResult(new Consumer() {
    @Override
    public void accept(TransactionStatus transactionStatus) {
        //执行业务操作
    }
});

execute:有返回值场景

T execute(TransactionCallback action):有返回值的,需要传递一个TransactionCallback对象,在doInTransaction方法中做业务操作

上一篇:《APUE》读书笔记—第十章信号(中)


下一篇:2014年3月 TIOBE 编程语言排行榜单