@Transactional
事者,生于虑,成于务,失于傲。——管仲
如果想让该类或方法被事务支持,则可以加上@Transactional注解
@Transactional有几个参数:
value/transactionManager——是用来指定事务管理器,这个不太常用
timeout——事务超时时间,为传播特性为PROPAGATION_REQUIRES_NEW和PROPAGATION_REQUIRED定制,创建新事务时旧事务的超时时间,出场率也不是特别高
下面的则是常用的参数
readOnly——是否为只读事务,如果为true时,进行查询操作效率会更高,但不能进行除查询外的操作,会报错
rollbackFor/rollbackForClassName——指定需要回滚的异常
noRollbackFor/noRollbackForClassName——指定不需要回滚的异常
默认对编译异常不会滚
对非受检异常回滚,例如RuntimeException就会回滚事务
isolation——配置隔离级别
事务丢失
回滚丢失——另一个事务回滚导致当前事务丢失
覆盖丢失——另一个事务提交导致当前事务丢失
org.springframework.transaction.annotation.Isolation枚举类下面有这样几种
DEFAULT——使用你JDBC默认的隔离级别
Read uncommitted脏读——当前事务能读到另一个事务执行后还未提交的数据
事务A读取了事务B中尚未提交的数据。如果事务B回滚,则A读取使用了错误的数据
例如A和B同时执行,B执行了SQL还没提交事务,A查询时看到了当前数据为B刚刚修改的,这个时候如果B回滚了,则A使用了错误数据
Read committed会产生不可重复读——当前事务能读到另一个事务提交修改后的数据
不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
例如A和B同时执行,A查询到B提交前的数据,B执行了修改SQL提交了事务以后,A再查询能看到B修改后的结果
但对新增和删除仍然和脏读一样,能看到新增/删除后未提交事务的数据
Repeatable read会产生幻读——当前事务能读到另一个事务提交新增/删除后的数据
在事务A多次读取构成中,事务B对数据进行了新增操作,导致事务A多次读取的数据不一致。
例如A和B同时执行,A能读取到 B执行了新增/删除SQL并提交了事务后的数据
Serializable避免发生以上事务丢失、脏读、幻读、不可重复读情况,性能低下
propagation——配置事务传播特性
例如在一个service调用另一个service中的方法时,需要配置
注意,如果是同一个
service下,如果需要事务支持,需要注入它本身,然后再调用注入的service执行方法,否则会导致事务生效,因为调用方法需要经过spring容器管理
例如:A调用B,B配置下列传播特性后
无事务:
PROPAGATION_NEVER——如果A有事务则抛异常(导致项目启动失败)
PROPAGATION_NOT_SUPPORTED——如果A没事务,B也没有。如果有则挂起A的事务,B无事务执行后A事务继续生效
有则用,无则不用:
PROPAGATION_SUPPORTS——如果A没有事务,则B也无事务,有事务则B用A的事务
有事务:
PROPAGATION_REQUIRES_NEW——如果A没有事务则创建一个B的,如果A有事务,挂起A的事务,B创建事务结束后A继续生效,不被B影响
PROPAGATION_NESTED——如果A没事务则创建一个B的,有事务则嵌套事务,B出异常不影响A,A出异常会回滚B
PROPAGATION_REQUIRED——默认,如果A没有事务则创建事务,有则用A的事务
PROPAGATION_MANDATORY——如果A没有事务,抛出异常(导致项目启动失败),有则用A的事务
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 蒋立坤的博客!
评论
Va




