参考:https://blog.youkuaiyun.com/qq_45559559/article/details/136984798
事物概念: 将一组操作封装成一个执行单元,要么全部成功,要么全部失败。
事物特性:
- 原⼦性:所有操作,要么全部成功,要么全部失败
- 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏
- 持久性:事务处理结束后,对数据的修改就是永久的
- 隔离性:数据库允许多个并发事务同时对其数据进⾏读写和修改的能⼒,隔离性可以防⽌多个事务
并发执⾏时由于交叉执⾏导致数据不⼀致。
事物隔离:
- 读未提交(READ UNCOMMITTED):读未提交,可以看到其他事务中未提交的数据,可能产生脏读
- 读已提交(READ COMMITTED):能读取到已经提交事务的数据,因此不会有脏读。但是事物在执行过程中,不同时间执行同一sql查询到的结果可能不同,即产生不可重复读
- 可重复读(REPEATABLE READ):默认隔离级别,确保同一事物多次查询结果一致,会导致其他事物提交的数据无法被查到,但是本事物新增数据失败,即幻读。
- 序列化(SERIALIZABLE):事务最⾼隔离级别,强制事务排序,使之不会发⽣冲突,从⽽解决了脏读、不可重复读和幻读问题,但因为执⾏效率低
数据库事物和Spring事物的关系
- Spring本身并不实现事物,Spring事物是依赖于数据库事物实现的,数据库事物是通过锁实现的,所以最终都是对锁的操作
- Spring事物是对数据库事物的包装,如果数据库没事物,那么Spring事物会失效
- Spring事物只有在捕获异常时候才会终止或回滚数据库相关操作,异常指定是通过参数rollbackFor,如果程序中try catch捕获了异常而没抛出,事物是不会终止或回滚
- Spring事物会回滚同一事物中所有的数据库操作
- Spring控制事物提交、回滚是通过与数据库的连接实现的,只需要保证一个事物里的多个操作使用的都是同一个连接即可(实现方式是通过ThreadLocal)
Spring 事务的传播机制
-
支持当前事务
- REOUIRED(需要有):如果当前方法没有事务,新建一个事务,如果已经存在一个事务中,则加入到这个事务中。
- SUPPORTS(可以有):支持当前事务,如果当前没有事务,就以非事务方式执行。
- MANDATORY(强制有):使用当前的事务,如果当前没有事务,就抛出异常。
-
不支持当前事务
- REQUIRES NEW:新建事务执行,如果当前存在事务,把当前事务挂起。
- NOT SUPPORTED: 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
-
NESTED(嵌套事务):如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION REOUIRED 类似的操作。
事物生效情况
方法A调用方法B,如果A和B方法在同一个类中:
- 如果A加@Transactional注解,B加不加@Transactional注解,事务是有效的,则AB在同一事务中。
- 如果A不加@Transactional注解,B加不加@Transactional注解,事务都是无效的。
注意:A没有事物,B加了事物情况下,如果需要B事物生效,可通过AopContext.currentProxy().xx()调用
方法A调用方法B,如果A和B不在同一个类中:
- 如果A加@Transactional注解,B加不加@Transactional注解,事务是有效的。
- 如果A不加@Transactional注解,B加了@Transactional注解,只有B是有事务的;
- 如果A不加@Transactional注解,B不加@Transactional注解,A、B都是没有事务的。
注意事项:
- 使用@Transactional时没指定rollbackFor,默认会回滚RuntimeException 和 Error,所以要设置
Spring和jdbc的关系
参考:https://www.jianshu.com/p/004c581c62cf
Spring和jdbc都可以独自管理事物,也可以一起管理事物
- 创建数据库连接
- 检测到@Transactional的业务类,通过动态代理生成增强类
- 代理类通过Transaction Manager来管理事务(开启、提交、回滚等),Transaction Manager调用jdbc的connection来管理事物
Spring事物实现原理
参考:https://blog.youkuaiyun.com/cy973071263/article/details/136088380
Spring事物依靠AOP实现,做逻辑的增强。