刚性事务(分布式事务-柔性事务)
编程式
声明式
一 概念简述
- 一般情况下:每个数据库操作一个数据库连接,事物自动提交
- 自定义事务时:多个数据库操作由一个事务来控制是否提交或者回滚
- 控制原理:共享一个数据库连接,数据库连接存储于当前线程中,需要用到时; 直接从线程中获取,没有则新建并存储到线程中
- 事物管理器:控制事物的开启(关闭自动提交)、提交、回退
二 注解@Transactional
- 为方法创建代理,方法内部的数据库操作共享一个数据库连接;
- 类内部方法之间调用事务不生效,只有使用其代理对象调用方法才可以
事务传播
- 谁给谁传播,传播了什么?
两个不同类之间方法调用,两者之间的事务如何进行处理;
事务往往在service层进⾏控制,如果出现service层⽅法A调⽤了另外⼀个service层⽅法B,A和B⽅法本
身都已经被添加了事务控制,那么A调⽤B的时候,就需要进⾏事务的⼀些协商,这就叫做事务的传播⾏
为。 - 传播机制(处理的方式)
A调⽤B,我们站在B的⻆度来观察来定义事务的传播⾏为:
标识 | 描述 |
---|---|
PROPAGATION_REQUIRED | 如果当前没有事务,就新建⼀个事务,如果已经存在⼀个事务中, |
加⼊到这个事务中。这是最常⻅的选择。 | |
PROPAGATION_SUPPORTS | ⽀持当前事务,如果当前没有事务,就以⾮事务⽅式执⾏。 |
PROPAGATION_MANDATORY | 使⽤当前的事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED | 以⾮事务⽅式执⾏操作,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NEVER | 以⾮事务⽅式执⾏,如果当前存在事务,则抛出异常。 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执⾏。如果当前没有事务,则执⾏与PROPAGATION_REQUIRED类似的操作。 |
Spring中事务的API
mybatis: sqlSession.commit();
hibernate: session.commit();
PlatformTransactionManager
public interface PlatformTransactionManager
此接⼝是Spring的事务管理器核⼼接⼝。Spring本身并不⽀持事务实现,只是负责提供标准,应⽤底层⽀持什么样的事务,需要提供具体实现类。此处也是策略模式的具体应⽤。
在Spring框架中,也为我们内置了⼀些具体策略,例如:DataSourceTransactionManager , HibernateTransactionManager 等
等。( 和 HibernateTransactionManager 事务管理器在 spring-orm-5.1.12.RELEASE.jar 中)
Spring JdbcTemplate(数据库操作⼯具)、Mybatis(mybatis-spring.jar)————>
DataSourceTransactionManager
Hibernate框架 ——————> HibernateTransactionManager
DataSourceTransactionManager 归根结底是横切逻辑代码,声明式事务要做的就是使⽤Aop(动态代理)来将事务控制逻辑织⼊到业务代码