spring事务
spring事务NESTED和REQUIRE_NEW的区别
NESTED 不会开启新的事务,相当与保存点。
REQUIRE_NEW开启一个新的事务,只要事务关联的方法没有异常,就会提交,和外部的事务没有关系。
我们先定义3个事务,如下:
- 父事务P,向数据库表中插入id为0的行。
- 子事务S1,向数据库表中插入id为1的行。
- 子事务S2,向数据库表中插入id为2的行。
父事务的方法m调用了子事务的方法m1和m2。如下
m(){
m1();
m2();
}
如有父事务P是默认的REQUIRE,子事务是REQUIRE_NEW:
- 如果父事务发生了异常,那么父事务回滚,子事务提交。数据库中记录为1,2
调用逻辑如下:m(){ m1(); m2(); throw e; //父事务发生了异常,子事务正常 }
- 如果子事务发生了异常,那么子事务回滚,父事务也回滚,父方法相当于也发生了异常。 数据库中结果为1,因为m1没发生异常且独立提交。
m(){ m1(); m2(); //throw e; 子事务S2方式了异常 }
- 如果子事务发生了异常,那么子事务回滚,父事务捕获并未重新抛出异常,父方法相当于没发生异常,则父事务不回滚。 数据库中结果为0,1
m(){ try{ m1(); m2(); //throw e; 子事务S2方式了异常 }catch(e){} }
如有父事务是默认的REQUIRE,子事务是NESTED:
- 如果父事务发生了异常,那么父事务回滚,子事务也回滚。数据库中没有记录。
调用逻辑如下:m(){ m1(); m2(); throw e; //父事务发生了异常,子事务正常 }
- 如果子事务发生了异常,那么子事务回滚,父事务也回滚,父方法相当于也发生了异常。 数据库中没有记录。
m(){ m1(); m2(); //throw e; 子事务S2方式了异常 }
- 如果子事务发生了异常,那么子事务回滚,父事务捕获并未重新抛出异常,父方法相当于没发生异常,则父事务不回滚。 数据库中结果为0,1
m(){ try{ m1(); m2(); //throw e; 子事务S2方式了异常 }catch(e){} }
如有父事务是默认的REQUIRE,子事务是REQUIRE:在上述第三种情况下,整个事务都会回滚,这就是REQUIRE和NESTED的区别。