赞
踩
提交(commit):
将未存储的SQL语句写入数据库表;
保留点(savepoint):
事务处理中设置的临时占位符(placeholder),可以对它
发布回退(与回退整个事务处理不同)。
保留点越多越好,越多回退会更灵活。
Spring Framework对事务管理做了一层抽象:TransactionManager,它是一个空接口。
PlatformTransactionManager 接口继承了TransactionManager,是事务管理的核心接口,包含了事务获取、提交、回滚的三个方法。
不同数据访问技术对应的PlatformTransactionManager实现:
TransactionManager类 | 数据访问技术 | 举例 |
---|---|---|
DataSourceTransactionManager | 在仅使用JDBC时使用 | Spring Boot 默认使用JDBC来控制事务 |
JpaTransactionManager | 在使用JPA时使用。同时在实现时还可能使用JDBC | |
HibernateTransactionManager | 在使用Hibernate时使用。同时在实现时还可能使用JDBC | |
JtaHibernate | 在使用全局事务(也就是使用应用程序服务器的分布式事务管理功能)时使用。此时可以使用任何数据访问技术 |
TransactionDefinition接口描述了事务定义,包含了几个与事务密切相关的属性:
事务传播性定义了7个级别,规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:
A方法调用B方法,B定义了以下传播行为:
传播行为类型 | 值 | 规则 | 举例 |
---|---|---|---|
PROPAGATION_REQUIRED 请求事务(required) | 0(默认) | 当前有事务就用当前事务,没有事务就重启一个事务。 | A无事务,B开启一个新事务; A有事务,那么B加入A的事务。B异常,一起回滚。 |
PROPAGATION_SUPPORTS 可支持事务 | 1 | 事务不是必须的,可以有也可以没有 | A无事务,B也无; A有事务,那么B加入A的事务。 |
PROPAGATION_MANDATORY 强制事务(mandatory,强制的) | 2 | 必须有一个事务,否则报错 | A无事务,就抛出异常;===>强制必须有事务 A有事务,那么B加入A的事务。 |
PROPAGATION_REQUIRES_NEW 请求新事务 | 3 | 新启动一个事务,如果当前存在一个事务则将其挂起 | A无事务,B新建事务; A有事务,B新建一个事务,且与A的事务独立。B异常,B回滚;A如果吃掉了B的异常,不回滚。 |
PROPAGATION_NOT_SUPPORTED 不支持事务 | 4 | 不支持事务,以非事务方式运行 | A无事务,B也无; A有事务,B把A的事务挂起,无事务执行 |
PROPAGATION_NEVER 拒绝事务 | 5 | 不支持事务,如果当前存在一个事务则抛异常 | - |
PROPAGATION_NESTED 嵌套事务(nested,嵌套) | 6 | 如果当前存在一个事务,则在该事务内再启动一个事务 | A无事务,B创建新事务; A有事务,B创建其子事务。==》父事务回滚,子也回滚。子事务异常,回滚;A如果吃掉了B的异常,不回滚。 B方法被调用时创建了一个保存点,B异常A不一定回滚。 |
对应数据库的四个隔离级别定义了4种隔离类型,默认隔离级别设置为-1,使用底层数据源的配置。
比如:mysql默认REPEATABLE_READ;Oracle和pg默认READ_COMMITTED。
@EnableTransactionManagement
;@Transactional(rollbackFor = Exception.class, propagation = Propagation.PROPAGATION_REQUIRED)
属性 | 默认值 | 作用 |
---|---|---|
transactionManager 或者value | transactionManager | 指定事务管理器 |
propagation | REQUIRED | 事务传播性 |
isolation | DEFAULT | 事务隔离级别 (使用的同时需要底层数据库支持这些值) |
timeout | TIMEOUT_DEFAULT,-1 | 事务超时时间; 超时自动回滚事务。 |
readOnly | false | 是否为只读事务;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。 |
rollbackFor rollbackForClassName | java.lang.RuntimeException或者子类 | 异常时回滚,可用于单元测试; |
noRollbackFor | java.lang.Exception或者子类 | 当期待的异常发生时,不回滚 |
@Transactional
作用域作用域 | 说明 |
---|---|
类 | 表示类中的所有公共方法都被事务化 |
方法 | 优先级高于类的作用域 |
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
目标方法声明式调用 @Transactional,通过AOP代理,目标方法形成一个切面对象,在spring的bean的初始化过程中,创建代理对象注册到IOC容器中。方法执行前先把事务自动提交设置为false;方法执行时如果没有异常,会自动将事务提交。默认会对方法中的RuntimeException和Error进行回滚。
@Autowired
的对象调用,也可以从ApplicationContext中获取自己的代理对象操作这个方法。proxy-target-class=true
,那么基于类的代理(CGLIB动态代理)将起作用;false
,那么标准的JDK基于接口的代理将起作用。public
或public final
修饰符的方法;public
的非final的实例方法,其他方法均无效;直接用@Transactional 注解,无需自己管理事务,Spring Boot 默认使用DataSourceTransactionManager 来管理事务。
@Transactional注解的value属性就是用来指定具体TransactionManager的,通过id或者name来指定唯一一个TransactionManager。
@Transactional(value = "database2TransactionManager")
public void test(String a) {
// business operation
}
在使用Transactional注解的时候,通过value指定不同的事务管理器。
import org.neo4j.ogm.session.SessionFactory; import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; import org.springframework.data.transaction.ChainedTransactionManager; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import javax.persistence.EntityManagerFactory; @Configuration public class TransactionalConfig { /** * pg事务管理器 (默认) */ @Bean @Primary public JpaTransactionManager transactionManager(EntityManagerFactory emf) { return new JpaTransactionManager(emf); } /** * 定义neo4j事务管理器 */ @Bean("neo4jTransactionManager") public Neo4jTransactionManager neo4jTransactionManager(SessionFactory sessionFactory) { return new Neo4jTransactionManager(sessionFactory); } /** * 多事务管理器 * ChainedTransactionManager只是同时开启两个事务,自动的对两个事务,同时开启,同时提交(或回滚)。它对多个数据写数据,并不是一个原子操作,不能像XA那样保证对数据操作的完整性,一致性。 看源代码:它用一个列表来管理多个数据源的事务管理器。 */ @Autowired @Bean(name = "multiTransactionManager") public PlatformTransactionManager multiTransactionManager( Neo4jTransactionManager neo4jTransactionManager, JpaTransactionManager pgTransactionManager) { return new ChainedTransactionManager( neo4jTransactionManager, pgTransactionManager); } }
有个坑:如果在junit中测试(加上@Transactional):无论如何都不能成功提交,会rollback。
XA是分布式事务规范,定义了分布式事务模型。定义了以下四个角色:
JTA是java对XA规范的实现。
AP告诉TM要开始事务,TM协调RM并将事务的xid分配给每个RM。
优化两阶段单点故障问题,但是不一致问题依然无法解决。
超时机制:如果preCommit消息执行成功,一定时间后还没有收到doCommit消息,则会认为TM挂掉了,自己执行doCommit。
针对每个操作,都要注册一个与其对应的确认、撤销操作。
A调用B时,通过MQ来调用,将调用信息放MQ中。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。