Java 在Spring中回滚嵌套事务中的所有DB提交
我有以下嵌套事务的服务布局:Java 在Spring中回滚嵌套事务中的所有DB提交,java,spring,nested,rollback,spring-transactions,Java,Spring,Nested,Rollback,Spring Transactions,我有以下嵌套事务的服务布局: @Component public class Main implements RPCInterface { @Autowired private ServiceA serviceA; @Autowired private ServiceB serviceB; @Autowired private ServiceC serviceC; @Override @Transactional (value="txManager", p
@Component
public class Main implements RPCInterface {
@Autowired
private ServiceA serviceA;
@Autowired
private ServiceB serviceB;
@Autowired
private ServiceC serviceC;
@Override
@Transactional (value="txManager", propagation=Propagation.REQUIRED, rollbackFor={ExceptionOne.class, ExceptionTwo.class, ExceptionThree.class})
public void outerMethod() throws ExceptionO {
try {
serviceA.methodA();
serviceB.methodB();
serviceC.methodC();
} catch (ExceptionOne e) {
throw new ExceptionO(e.getMessage, e);
} catch (ExceptionTwo e) {
throw new ExceptionO(e.getMessage, e);
} catch (ExceptionThree e) {
throw new ExceptionO(e.getMessage, e);
}
}
}
@Service
public class ServiceA implements SA {
@Autowired
private ServiceA1 serviceA1;
@Override
public void methodA() {
serviceA1.methodA1();
}
}
@Service
public class ServiceA1 implements SA1 {
@Autowired
private ServiceDBTable1 serviceDBTable1;
@Autowired
private ServiceA1A serviceA1A;
@Transactional
@Override
public void methodA1() {
serviceDBTable4.callToMapper4();
serviceA1A.methodA1A();
}
}
@Service
@Transactional (value="txManager", propagation=Propagation.REQUIRED)
public class ServiceA1A implements SA1A {
@Autowired
private ServiceDBTable2 serviceDBTable2;
@Override
public void methodA1A() {
serviceDBTable1.callToMapper1();
}
}
@Service
public class ServiceB implements SB {
@Autowired
private ServiceDBTable3 serviceDBTable3;
@Override
@Transactional (value="txManager", propagation=Propagation.REQUIRED)
public void methodB() {
serviceDBTable3.callToMapper3();
}
}
@Service
public class ServiceC implements SC {
@Override
public void methodC() throws ExceptionThree {
// code that throws ExceptionThree
}
}
我需要在ServiceA
和ServiceB
嵌套调用中进行所有DB调用,以便在ServiceC#methodC()
引发异常时回滚(或者任何引发异常的调用--ServiceA
或ServiceB
)
我试图使
Main#outerMethod
与REQUIRED
传播进行事务处理,但似乎数据库提交没有回滚。我甚至用rollboor
指定了特定的类,但提交仍然存在。有人知道如何解决这个问题吗?因为没有代码,所以很难确定。
但是,只有当方法是公共的时,事务才起作用。私有方法没有代理,因此不存在对它们的事务支持
请通读以了解更多详细信息
如果您仍在努力寻求更好的帮助,请发布代码。我所做的是将
ServiceB.methodB()
和ServiceC.methodC()
调用迁移到ServiceA.methodA()
,并使methodA()
事务性,同时抛出methodA()的所有异常
和基于这三个异常的回滚(我的逻辑实际上允许我这样做):
内部方法都是服务调用(一个服务/对象,调用另一个服务/对象),因此它们必须是公共的。问题是上述配置是否应该工作。大量分散的代码使得发布实际代码变得很困难,因此上面的压缩版本就是这样。为什么不将innerMethodThree与innerMethod_1a和2a放在同一个事务中?@Simon我如何做到这一点
innerMethodThree
必须在1)和2)之后调用。在outerMethod上设置@Transactional,对于1a和1a不需要新的2a@Simon我用一个更具体的例子更新了这个问题。我从ServiceA1.methodA1()
和ServiceB.methodB()
中删除了@Transactional
,并将其放在Main#outerMethod()
上,但是回滚没有发生。我的意思是,您可以在rollboor子句中添加ExceptionO
@Component
public class Main implements RPCInterface {
@Autowired
private ServiceA serviceA;
@Override
public void outerMethod() throws ExceptionO {
try {
serviceA.methodA();
} catch (ExceptionOne e) {
throw new ExceptionO(e.getMessage, e);
} catch (ExceptionTwo e) {
throw new ExceptionO(e.getMessage, e);
} catch (ExceptionThree e) {
throw new ExceptionO(e.getMessage, e);
}
}
}
@Service
public class ServiceA implements SA {
@Autowired
private ServiceA1 serviceA1;
@Autowired
private ServiceB serviceB;
@Autowired
private ServiceC serviceC;
@Override
@Transactional (value="txManager", propagation=Propagation.REQUIRED, rollbackFor={ExceptionOne.class, ExceptionTwo.class, ExceptionThree.class})
public void methodA() throw ExceptionOne, ExceptionTwo, ExceptionThree {
serviceA1.methodA1();
serviceB.methodB();
serviceC.methodC();
}
}
@Service
public class ServiceA1 implements SA1 {
@Autowired
private ServiceDBTable1 serviceDBTable1;
@Autowired
private ServiceA1A serviceA1A;
@Transactional
@Override
public void methodA1() {
serviceDBTable4.callToMapper4();
serviceA1A.methodA1A();
}
}
@Service
@Transactional (value="txManager", propagation=Propagation.REQUIRED)
public class ServiceA1A implements SA1A {
@Autowired
private ServiceDBTable2 serviceDBTable2;
@Override
public void methodA1A() {
serviceDBTable1.callToMapper1();
}
}
@Service
public class ServiceB implements SB {
@Autowired
private ServiceDBTable3 serviceDBTable3;
@Override
@Transactional (value="txManager", propagation=Propagation.REQUIRED)
public void methodB() {
serviceDBTable3.callToMapper3();
}
}
@Service
public class ServiceC implements SC {
@Override
public void methodC() throws ExceptionThree {
// code that throws ExceptionThree
}
}