本文共 1120 字,大约阅读时间需要 3 分钟。
Spring的Transactional注解主要有以下功能:
1. 标注在方法上,如果该方法掉了多个别的方法,每个方法都有对数据库做数据更改,如果这些更改需要保持一致性,这时就可以用到这个注解。
2. 用这个注解一个前提是这些方法都用的是本地数据库连接,也就是说只对于本地数据库连接(事务)有效,对于分布式事务,这个注解是没办法完成远程事务的回滚和提交的。
3. 这个注解的isolation属性,对应的是数据库的四种隔离级别,比如read uncommitted, read committed, repeatable read, serializable。对于Mysql, 默认是repeatable read,而SqlServer和Oracle数据库,默认是read committed。当修改该值时,比如改成read uncommitted,那在该数据库连接中,就可以看到别人未提交的数据。我们也可以在一些数据库客户端可视化工具中,比如SqlYog中修改连接的隔离级别,这样就可以查看到未提交的数据。级别越高,要求越严格,并发性越差。
4. 这个注解的propagation属性,我们重点关注两个,一个是REQUIRED, 另外一个是REQUIRES_NEW。比如有这样一个方法:
@Transactional()public void methodA(){ methodB(); methodC(); xxxxx;}@Transactional()public void methodB(){ xxxx;}@Transactional(propagation = REQUIRES_NEW)public void methodC(){ xxxx;}
默认propagation属性值是REQUIRED,以我们这段伪代码为例,methodA和methodB默认都是REQUIRED,这样当A方法或者B方法出错抛出异常时,A和B都会回滚,因为公用的是同一个事务。而C方法由于是开启了一个新事务,所以C与A/B互不影响。
5. Transactional注解回滚的条件是有异常才会回滚。也就是以来异常机制。如果你想让事务回滚,你的代码要么自动抛异常,要么手动抛一个异常。实际上Spring框架会对标注了这个注解的类用代理的方式生成一个新的类,从而帮助你完成回滚的代码,回滚的代码是放在了catch{}块中(猜测,没有实际验证过)。
6. 如果是Springboot程序,那上边的这段伪代码,即使C方法设置的是REQUIRES_NEW,也不会生效,C方法也会跟A, B公用一个事务。具体解决办法,可以参考网上文章。
转载地址:http://mkcqi.baihongyu.com/