Spring 抽象方法的事务

case 1:抽象方法上的事务注解是否会生效?

@Component
public abstract class BaseService {

    @Autowired
    protected JdbcTemplate jdbcTemplate;

    @Transactional(rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ)
    public abstract void abstractInsert();
}

@Component
public class BaseServiceImpl extends BaseService {

	@Override
    // @Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE)
    public void abstractInsert() {
        System.out.println(IsolationUtils.getCurrentIsolation());
        jdbcTemplate.execute("INSERT INTO `local_db`.`t_sys_user` (id) VALUES(NULL);");
    }
}

打印结果:打印 REPEATABLE_READ,说明会生效。

case 2:父子事务方法都有事务注解,采用谁的?

@Component
public class BaseServiceImpl extends BaseService {

	@Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE)
    public void abstractInsert() {
        System.out.println(IsolationUtils.getCurrentIsolation());
        jdbcTemplate.execute("INSERT INTO `local_db`.`t_sys_user` (id) VALUES(NULL);");
    }
}

放开子方法上的事务注释,打印:SERIALIZABLE,说明就近使用子的。

case 3:父子事务方法互相调用时,使用谁的事务注解中的规则?

@Component
public abstract class BaseService {

    @Autowired
    protected JdbcTemplate jdbcTemplate;

    @Transactional(rollbackFor = Exception.class)
    public void overrideAbstractInsert() {
        TransactionSynchronizationManager.setCurrentTransactionName("Parent overrideAbstractInsert");
        jdbcTemplate.execute("INSERT INTO `local_db`.`t_sys_user` (name) VALUES('parent trx');");
        ((BaseService) AopContext.currentProxy()).doOverrideAbstractInsert();
        int i = 1 / 0;
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public abstract void doOverrideAbstractInsert();
}
@Component
public class BaseServiceImpl extends BaseService {

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    @Override
    public void doOverrideAbstractInsert() {
        System.out.println(TransactionSynchronizationManager.getCurrentTransactionName());
        jdbcTemplate.execute("INSERT INTO `local_db`.`t_sys_user` (name) VALUES('child trx');");
    }
}

结论:

  1. 需要根据事务方法入口是谁而定。
  2. 当起始的事务方法内部再次调用其他的事务方法,事务规则是否生效,取决于是否使用事务代理对象调用的事务方法。
  3. 若内部调用的事务方法是一个抽象方法,事务注解的应用规则与 case 2 相同。

证明子事务方法使用的事务注解为子类重写方法上的事务注解:

  1. 子事务方法中输出的事务名称为:org.xxx.BaseServiceImpl.doOverrideAbstractInsert,说明使用的子事务 > 说明事务传播行为使用的 Propagation.REQUIRES_NEW > 说明没有使用抽象方法上的 Propagation.REQUIRED
  2. 子事务方法中数据插入成功:虽然父事务抛出了异常,但没有影响子事务的数据添加 > 说明使用的是 Propagation.REQUIRES_NEW > 说明没有使用抽象方法上的 Propagation.REQUIRED
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值