试图防止内部事务回滚。如果内部事务响应未成功,则外部事务应回滚,但内部事务应保存数据。
BWDisplay::setTemplate($template, array $params = array(), $locale = null)
答案 0 :(得分:2)
将内部事务方法配置为Propagation.REQUIRES_NEW
,以便在方法完成外部事务方法是否回滚时,它将始终提交(即保存数据)。
还要确保外部方法不会自行调用内部方法,因为@Transactional
在这种情况下不起作用(请参阅docs中的方法可见性和@Transactional部分)。
它们应该驻留在外部方法调用内部方法的bean的不同bean中:
@Service
public class Service1 {
@Autowired
private Service2 service2;
@Transactional(rollbackFor=Exception.class)
public void test1(Account account) throws Exception {
DOA.save(account);
status = service2.test2(account);
if(status!='SUCCESS'){
throw new Exception("Api call failed");
}
}
}
@Service
public class Service2{
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void test2(Account account) {
response // API Call
DOA.save(response);
return response.status;
}
}
答案 1 :(得分:0)
@Transactional
方法将忽略 Test2
,并且该调用是单个事务的一部分。
Spring文档所说的两件事-
方法可见性和@Transactional
使用代理时,应应用@Transactional批注 仅适用于具有公众知名度的方法。如果您做受保护的注释, 带有@Transactional批注的私有或包可见方法 不会引发任何错误,但是带注释的方法不会显示 配置的交易设置。考虑使用AspectJ(请参阅 下面)是否需要注释非公共方法。
代理模式
在代理模式(默认)下,仅外部方法调用 通过代理进入的邮件被拦截。这意味着 自我调用实际上是目标对象内的一种方法 目标对象的另一种方法,不会导致实际 运行时的事务,即使被调用的方法标记有 @Transactional。
如果要保存内部方法的数据,则可以选择为Test2
方法启动新事务,这样就不会影响由Test1
开始的现有事务。
但是,即使您公开Test2
来自同一类的调用,它也不会启动新事务。
解决方案-
Propagation.REQUIRES_NEW