spring事务管理之TransactionDefinition
2. TransactionDefinition
TransactionDefinition 事务定义信息: (配置信息来自xml配置文件和注解)
包括事务的隔离级别,事务的传播特性,事务超时时间,事务只读特性.
这个接口中有很多常量:
* ISOLATION_xxx 事务隔离级别
* PROPAGATION_xxx 事务传播行为
* int getTimeout() 获得超时信息
* boolean isReadOnly() 判断事务是否只读
2.1. 事务隔离级别
事务四大特性 : ACID 原子性、一致性、隔离性、持久性
隔离性引发并发问题:脏读、不可重复读、虚读
* 脏读一个事务读取另一个事务未提交数据
* 不可重复读一个事务读取另一个事务已经提交 update 数据
* 虚读 一个事务读取另一个事务已经提交 insert 数据
事务隔离级别为了解决事务隔离性引发问题
* DEFAULT 默认级别 mysql REPEATABLE_READ 、 oracle READ_COMMITTED
* READ_UNCOMMITED 导致所有问题发生
* READ_COMMITTED 防止脏读、发生不可重复读和虚读
* REPEATABLE_READ 防止脏读、不可重复读,发生虚读
* SERIALIZABLE 防止所有并发问题
2.2 .事务的传播行为
传播行为解决问题:一个业务层事务调用另一个业务层事务,事务之间关系如何处理
事务的传播行为在jdbc规范中是没有定义的,jdbc规范只定义了事务的隔离级别.
为什么要有事务的传播行为,就是为了方便开发.
实际开发中的问题:会不会业务层方法之间的互相调用,这是种情况下会发生的,例如:
删除客户的同时,也要删除与客户相关联的订单.这时就会在CustomerService的deleteCustomer方法中调用OrderSerivce中的deleteOrder方法.
如果订单删除失败了,那么就不应该删除客户,所以这两个操作必须放到同一个事务中.
另一种情况:订单删除失败了,仍然要把客户删除,这两个操作也需要事务
传播行为解决的问题是:一个业务层的事务,调用另一个业务层事务,事务之间的关系如何处理.
七种传播行为
在Spring中定义了七中事务传播行为:
1. PROPAGATION_REQUIRED 支持当前事务,如果不存在就新建一个
* 删除客户时删除订单,处于同一个事务,如果删除订单失败,删除客户也要回滚
2. PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务
*删除客户时删除订单,如果删除客户时没有开启事务,那么删除订单也不使用事务.
3. PROPAGATION_MANDATORY支持当前事务,如果不存在,抛出异常
*删除客户时删除订单,如果在删除订单时没开事务,则抛出异常.
4. PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务
* 生成订单,发送通知邮件,通知邮件会创建一个新的事务,如果邮件失败,不影 响订单生成事务.
5. PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务
6. PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常
7. PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行
* 依赖于 JDBC3.0 提供 SavePoint 技术
* 删除客户删除订单, 在删除客户后,设置SavePoint, 执行删除订单,删除订单 和删除客户在同一个事务,删除订单失败,事务回滚 SavePoint , 由用户控制是事务 提交还是回滚
重点:
PROPAGATION_REQUIRED 一个事务,要么都成功,要么都失败
PROPAGATION_REQUIRES_NEW 两个不同事务,彼此之间没有关系 一个事务失败了不影响另一个事务
PROPAGATION_NESTED 一个事务,在A事务调用 B过程中, B失败了,回滚事务到之前SavePoint ,用户可以选择提交事务或者回滚事务