spring中最使人疑惑的是嵌套事务PROPAGATION_NESTED和新建事务PROPAGATION_REQUIRES_NEW
两者在当前不存在事务情况下都新建事务,最大区别在于存在当前事务情况下的处理方式
-
PROPAGATION_REQUIRES_NEW
如果当前执行环境存在事务,挂起当前事务,重新建立打开新事务,当前事务和新建事务直接相互不产生影响,比如正在工作来了个普通推销电话,放下手头的事情接过电话(挂起当前事务),继续完成未完成的工作(恢复当前事务)
-
PROPAGATION_NESTED
它是已经存在事务的一个真正的子事务. 潜套事务开始执行时, 它将取得一个 savepoint. 如果这个嵌套事务失败, 我们将回滚到此 savepoint. 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交或回滚.
也就是外部事务提交子事务才能commit,外部事务回滚子事务也回滚
如果内部事务回滚将不影响外部事务,内部事务回滚时只回滚到savepoint,当然内部事务可以通过回滚手动抛出异常影响外部事务(业务需求而定),当然有很多种组合
ServiceA {
/**
* 事务属性配置为 PROPAGATION_REQUIRED
*/
void methodA() {
try {
ServiceB.methodB();
} catch (SomeException) {
// 执行其他业务, 如 ServiceC.methodC();
}
}
}
ServiceB {
/**
* 事务属性配置为 PROPAGATION_NESTED
*/
void methodB() {
}
}
使用嵌套事务前提条件
1.设置transactionManager的nestedTransactionAllowed为true,默认是false
2.java.sql.Savepoint必须在jdk1.4+
3.Connection.getMetaData().supportsSavepoints()必须为true ,即jdbc drive必须支持JDBC3.0