@Transactiona注解的使用
https://blog.****.net/yalishadaa/article/details/70261973
当同一个应用程序或者不同应用程序中的多个事务在同一个数据集上并发执行时,可能会出现许多意外的问题
并发事务所导致的问题可以分为下面三种类型:
脏读: 对于两个事物T1,T2, T1 读取了已经被T2更新但还没有被提交的字段. 之后,若T2回滚,T1读取的内容就是临时且无效的.
不可重复读:对于两个事物T1,T2, T1 读取了一个字段,然后T2更新了该字段.之后,T1再次读取同一个字段, 值就不同了.
幻读:对于两个事物T1,T2, T1 从一个表中读取了一个字段,然后T2在该表中插入了一些新的行.之后,如果T1再次读取同一个表,就会多出几行.
从理论上来说, 事务应该彼此完全隔离,以避免并发事务所导致的问题.然而,那样会对性能产生极大的影响,因为事务必须按顺序运行.
在实际开发中, 为了提升性能,事务会以较低的隔离级别运行.
事务的隔离级别可以通过隔离事务属性指定
事务的隔离级别要得到底层数据库引擎的支持,而不是应用程序或者框架的支持.
Oracle支持的2种事务隔离级别:READ_COMMITED, SERIALIZABLE
Mysql支持4中事务隔离级别.
事务的回滚通过@Transactional 注解完成。
1.设置事务的隔离级别:
可以在 @Transactional的isolation属性中设置隔离级别.
2.设置事务的回滚属性
默认情况下只有未检查异常(RuntimeException和Error类型的异常)会导致事务回滚.而受检查异常不会.
事务的回滚规则可以通过@Transactional注解的rollbackFor和noRollbackFor属性来定义.
ex:
[java] view plain copy
- @Transactional(propagation = Propagation.REQUIRES_NEW,isolation = Isolation.READ_COMMITTED,
- noRollbackFor = {UserAccountException.class},
- )
[java] view plain copy
- UserAccountException
造成的异常都会被忽略。
[java] view plain copy
- rollbackFor: 遇到时必须进行回滚
- noRollbackFor: 一组异常类,遇到时必须不回滚
3.设置超时属性
超时事务属性: 事务在强制回滚之前可以保持多久.这样可以防止长期运行的事务占用资源.
ex:
[java] view plain copy
- @Transactional(propagation = Propagation.REQUIRES_NEW,isolation = Isolation.READ_COMMITTED,
- noRollbackFor = {UserAccountException.class},
- timeout = 3)
如果在函数中有任务执行时间大于3秒,就算没有异常抛出也会强制回滚。
4.设置只读事务属性
表示这个事务只读取数据但不更新数据,这样可以帮助数据库引擎优化事务.
ex:
[java] view plain copy
- @Transactional(propagation = Propagation.REQUIRES_NEW,isolation = Isolation.READ_COMMITTED,
- noRollbackFor = {UserAccountException.class},
- readOnly = false,timeout = 1)