【发布时间】:2015-02-27 00:56:11
【问题描述】:
最近,我一直在使用 Spring boot + spring data jpa + hibernate。我在春季交易中遇到了一个问题。这是我的服务类和两个问题:
@Transactional
@Service
class MyService {
@Autowired
private MyRepository myRep;
public void method_A() {
try {
method_C();
.....
method_B();
} catch(Exception e) {}
}
public void method_B() {
Entity e = new Entity();
e.set(...);
myRep.save(e);
}
public void method_C() throws Exception {
....
}
}
1.如果method_C()方法抛出异常,我想捕获它并记录它,事务在method_B()方法中没有回滚,因为异常没有到达Spring框架。那么我应该怎么做才能从method_C() 捕获异常,同时不失去方法method_B() 被回滚的能力?
2.考虑新方法method_A()。
public void method_A() {
for(...) {
...
...
method_B();
}
}
我想循环调用method_B()。如果method_B() 中发生异常,我希望method_B() 的事务被回滚,但method_A() 不应该退出并且循环应该继续执行。我怎样才能做到这一点?
【问题讨论】:
-
不要捕获异常,spring 无论如何都会记录异常,包括完整的堆栈跟踪,所以为什么还要自己做呢。对于选项 2,只需在 for 循环中放置一个 try/catch。方法 B 仍然按原样运行(包括回滚),方法 a 仍然继续。如果您想要一些额外的异常处理,您总是可以编写一个 after throwing 方面来进行日志记录,或者添加一个 catch 但总是重新抛出异常(但由于 Spring 已经记录了这将是一个但多余的)。
-
如果我在循环中添加
try-catch块,事务不会在method_B()中回滚。实体被保存并提交到数据库。 -
这里的假设是methodA不在事务中,只有method B。
-
你的意思是如果只在方法
method_B()之前写@Transactional它应该表现得像你说的那样? -
不,因为那将是一个内部方法调用,并且因为 Spring 默认使用代理,所以根本没有事务。当您使用提前期或编译时编织时,您可以做到这一点。
标签: java spring hibernate jpa spring-data