又想到了小米,留下了不甘的泪水,哈哈哈哈
1. 事务传播行为的7种策略
REQUIRED
:必需的(默认值)
如果当前没有事务运行,则会开启一个新的事务;如果当前已经有事务运行,则方法会运行在当前事务中,“你没有,我开启,你有了,我加入”REQUIRES_NEW
:新事务
如果当前没有事务事务运行,则会开启一个新的事务;如果当前已经有事务运行,则会将原事务挂起,重新开启一个新的事务。当新的事务运行完毕后,再将原来的事务释放,“你没有我开启,你有了我造新的”SUPPORTS
:支持
如果当前有事务运行,则方法运行在当前事务中;如果没有事务运行,则不在事务中运行,“有就有,没有拉到”NOT_SUPPORTED
:不支持
如果当前事务运行,则会将事务挂起,如果当前没有事务运行,则它也不会运行在事务中,“有我不要,没有正好”MANDATORY
:强制
当前方法必须在事务中,如果没有事务,则直接抛出异常,“要干活必须有,没有就打死不干”NEVER
:不允许
当前方法不允许运行在事务中,如果当前已经有事务运行,则抛出异常,“要干活不准有,有了不干活”NESTED
:嵌套
如果当前没有事务运行,则开启一个新的事务;如果当前已经有事务运行,则会记录一个保存点,并继续运行在当前事务中。如果子事务运行中出现异常,则不会全部回滚,而是回滚到哦上一个保存点
在注解中,添加propagation属性即可修改
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void addPoint() {
System.out.println("addPoint 添加积分 ......");
}
2. Spring事务的三大核心
PlatformTransactionManager
:平台事务管理器,做事务控制TransactionDefinition
:事务定义,包括事务的隔离级别,事务的传播行为,是否为读写事务等等TransactionStatus
:事务状态,是否有保存点,是否完成…
3. 声明式事务
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="saveAndQuery"/>
<tx:method name="addMoney"/>
<tx:method name="subtractMoney"/>
</tx:attributes>
</tx:advice>
在这个 xml 的配置中,配置事务通知,需要指定事务管理器,并配置事务覆盖的方法,必要的还会配置事务传播行为。而这个<tx:advice>
标签的底层,其实是注册了一个 TransactionInterceptor
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable
可以发现它实现了 MethodInterceptor
接口!通过前面 AOP 部分的学习,我们知道 MethodInterceptor 接口是 AOP 增强的核心拦截器接口,利用 AOP 生成的代理对象中都会包含一组 MethodInterceptor 接口的实现类对象
注解式事务用到的两个注解@EnableTransactionManagement
,@Transactional
暂且这么多