初识spring事务传播机制的时候,脑子一头雾水,想呀一个事务也能搞出来那么多东西,这不是故意搞复杂了吗?当时真的是人越是菜的时候,越是比较自信。毕竟在以前学习数据库事务的时候,只有提交和回滚。当时也没有仔细研究,就随便背一下,应付面试而已,直到我遇到了一个让我很头疼的需求,一个请求需要调用三个方法,就假设为方法A、B和C,一般情况下,这三个方法都成功则提交,其中任何一个失败就回滚,而这次要求B失败不影响A、C,只回滚B本身操作的数据。在此情况下,挠破脑袋也想不到如何解决,差点直接对这个需求弃用spring了,用原生办法实现,建立两个数据库连接,B单独用一个连接处理。从网上仔细找了一下解决方案,有人说可以用spring事务传播机制处理,就仔细研究了一下,发现里面的功能真厉害,完美解决了这个问题。此上都是我研究spring事务的背景,下面开始我对spring事务的简单浅述。
{
A();
B();
C();
}
背景
数据库连接是和事务一一绑定的。
REQUIRED
在方法上直接加@Transactional,spring事务默认的传播机制就是REQUIRED,如果当前没有事务,则创建一个新的事务,如果当前存在事务,子方法加入当前事务,形成一个整体。
也就是说,使用REQUIRED,若是A、B和C方法都是使用的此机制,则他们都是在一个连接中执行,若有一个报错,则全部回滚。
类似于如下的代码:
{
conn = new Connection()
try{
A(conn);
B(conn);
C(conn);
conn.commit();
}catch(Exception e){
conn.rollback();
}
}
REQUIRES_NEW
在@Transactional(propagation = Propagation.REQUIRES_NEW)注解上加入此事务传播方式,挂起当前事务,新建一个事务处理此方法。此方式就可以实现我当时所遇到的问题。
假设方法A和C的事务传播机制采用REQUIRED,B方法采用REQUIRES_NEW,则方法A和C会由一个连接处理,B方法会由另一个连接处理。
{
conn = new Connection()
try{
A(conn);
try{
conn1 = new Connection()
B(conn1);
}catch(Exception e){
conn1.rollback();
}
C(conn);
conn.commit();
}catch(Exception e){
conn.rollback();
}
}