我在后端服务上使用了Controller-Service-Dao
模式,如下所示:
1.主计长
@RestController
public class A {
@Autowired
B b;
@GetMapping("/path")
public ResponseEntity methodA() throws Exception {
return ResponseEntity.ok(b.methodB());
}
}
1.服务层1
@Service
public class B {
@Autowired
E e;
@Transactional(dontRollbackOn = {Exception.class})
public Map methodB() throws Exception {
return e.methodE();
}
}
2.a.第二服务层
@Service
public class E {
@Autowired
C c;
@Transactional(dontRollbackOn = {Exception.class})
public Map methodE() throws Exception {
List<D> ds = c.inquiry();
for (D d : ds) {
try { // process every d here }
catch(Exception ex) {d.setStatus("FAIL!");}
c.save(d);
}
return new HashMap(){{ put("deleted_rows", c.delete()); }};
}
}
1.道
@Component
public class C {
public List<D> inquiry() {
Session session = sessionFactory.getCurrentSession();
return session.createQuery("from D").list();
};
public void save(D d){
Session session = sessionFactory.getCurrentSession();
session.save(d);
};
public int delete() {
sessionFactory.getCurrentSession().createQuery("delete from D where createdDate < :today")
.setParameter("today", today).executeUpdate();
}
}
以上是我的真实代码的简单版本。但是我想知道我应该做些什么来防止这个错误:意外回滚异常:事务已回滚,因为它已标记为仅回滚
当我看到日志时,确实在E.methodE()
方法内的try-catch
块中捕获了一个错误。我还看到成功删除行的休眠日志。但问题是它最后在提交时被回滚了。我应该做些什么来修复这个错误?这个事务注解的使用是否有错误?
1条答案
按热度按时间ffvjumwh1#
在JPA域中,几乎所有运行时异常都会导致将当前事务标记为仅回滚,请检查例如ExceptionConverterImpl#convert。原因非常明显:如果出现了问题,这意味着持久化上下文不再与DB同步(我们在持久化上下文中执行了更改,但未能持久化它们),最直接的“补偿”是回滚事务。
Spring的
Transactional#noRollbackFor
对于JPA域中引发的大多数异常都不能“按预期”工作,唯一的选择是以更准确的方式编写代码。