spring 事务

大纲:

  1. 声明式事务
  2. 编程式事务
  3. 事务传播行为

 

一、声明式事务

纳入spring事务管理只需要在方法或这类上@Transactional 就行了。

  1. 加在方法上表示这个方法纳入管理,加载类上表示整个类的方法纳入管理。方法和类上都声明则优先级顺序为方法>实现类>接口。
  2. 多数据源时@Transactional("DataSourceTransactionManager")注解中填写spring配置DataSourceTransactionManager的名称。
  3. @Transactional还可以指定隔离级别,超时等。
  4. 同类中yy方法直接调用xx,事务不生效。
  5. xx方法需要public权限。
  6. 抛出RuntimeException时生效,业务代码1没有编译时异常,可以生效,业务代码2有编译时异常,需要手动catch,手动回滚。
@Transactional
public void xx(){
  业务1;
try { 业务2; } catch (Exception e) { //回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } }

private void yy(){
  //事务无效
  xx();
}

 

二、编程式事务

PlatformTransactionManager

  1. DefaultTransactionDefinition指定超时,隔离级别等。
  2. 多数据源需要Qualifierspring指定配置DataSourceTransactionManager的名称。
  3. 声明式的不能做到每次分开提交回滚、控制粒度不如编程式的。例如在一个循环中,编程式的可以每次循环都新开事务提交或回滚。
    @Autowired
    @Qualifier("transactionManagerName")
    PlatformTransactionManager transactionManager;

    public void testx() {
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            //业务
            transactionManager.commit(status);
        } catch (Exception e) {
            transactionManager.rollback(status);
            e.printStackTrace();
        }
    }

 

三、事务传播行为

 

传播行为都发生在@Transactional注解的方法上,因为被注解的方法AOP会生成代理类,把autocommit=false然后,事务管理器会将connection对象放入threadloacl中,被调用方法会检查自己线程的事务管理器中treadlocal里面有没有connection,如果是纳入之前的管理就直接用这个connection对象,如果是新建事务或者非事务方式执行则重新获取一个connection对象。

其实类型归纳一下就2大种:支持调用者事务(1-3)、不支持调用者事务(4-6)、7的应用少和1类似

动作一共三种:以非事务方式执行,新建事务,报错

把他们组合一下:

支持类:支持调用者有事务,如果没有事务被调用方法则以非事务方式执行,新建事务,报错

不支持类:支持调用者有事务,如果有事务则以非事务方式执行,新建事务,报错

支持:支持调用我的方法有事务

 

posted @ 2018-03-15 20:11  扶不起的刘阿斗  阅读(125)  评论(0编辑  收藏  举报