下面是我正在尝试做的事情的快速概述。我想通过一个方法调用将记录推送到数据库中的两个不同表。如果有任何事情失败,我希望一切都回滚。因此,如果insertIntoB
失败了,我想要任何可以承诺的事情insertIntoA
被回滚。
public class Service {
MyDAO dao;
public void insertRecords(List<Record> records){
for (Record record : records){
insertIntoAAndB(record);
}
}
@Transactional (rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public void insertIntoAAndB(Record record){
insertIntoA(record);
insertIntoB(record);
}
@Transactional(propagation = Propagation.REQUIRED)
public void insertIntoA(Record record){
dao.insertIntoA(record);
}
@Transactional(propagation = Propagation.REQUIRED)
public void insertIntoB(Record record){
dao.insertIntoB(record);
}
public void setMyDAO(final MyDAO dao) {
this.dao = dao;
}
}
Where MyDAO dao
是一个使用mybatis映射到数据库的接口,并使用Spring注入进行设置。
现在如果insertIntoB
失败了,一切从insertIntoA
仍然被推送到数据库。我该如何纠正这种行为?
EDIT:
我修改了该类,以更准确地描述我想要实现的目标。如果我跑insertIntoAAndB
直接,如果有任何问题,回滚可以工作,但是如果我打电话insertIntoAAndB
from insertRecords
,如果出现任何问题,回滚将不起作用。
我找到了解决方案!
显然 Spring 无法拦截对事务方法的内部方法调用。所以我把调用事务方法的方法拿出来,放到一个单独的类中,回滚就可以正常工作了。以下是修复的粗略示例。
public class Foo {
public void insertRecords(List<Record> records){
Service myService = new Service();
for (Record record : records){
myService.insertIntoAAndB(record);
}
}
}
public class Service {
MyDAO dao;
@Transactional (rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public void insertIntoAAndB(Record record){
insertIntoA(record);
insertIntoB(record);
}
@Transactional(propagation = Propagation.REQUIRED)
public void insertIntoA(Record record){
dao.insertIntoA(record);
}
@Transactional(propagation = Propagation.REQUIRED)
public void insertIntoB(Record record){
dao.insertIntoB(record);
}
public void setMyDAO(final MyDAO dao) {
this.dao = dao;
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)