java - 如何防止 JPA 回滚事务?

标签 java hibernate spring jpa struts

调用的方法:
1. Struts Action
2.服务类方法(@Transactional注解)
3.Xfire web服务调用

包括 struts (DelegatingActionProxy) 和事务在内的一切都使用 Spring 配置。

持久化是通过 JPA/Hibernate 完成的。

有时网络服务会抛出未经检查的异常。我捕获了这个异常并抛出了一个已检查的异常。我不希望事务回滚,因为 Web 服务异常更改了当前状态。我已经注释了这样的方法:

@Transactional(noRollbackFor={XFireRuntimeException.class, Exception.class})
public ActionForward callWS(Order order, ....) throws Exception
  (...)
  OrderResult orderResult = null;

  try {
    orderResult = webService.order(product, user)
  } catch (XFireRuntimeException xfireRuntimeException) {
    order.setFailed(true);
    throw new WebServiceOrderFailed(order);
  } finally {
    persist(order);
  }
}

我仍然得到这个异常:

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly

当我尝试使用 junit 重现此事务时,事务未标记为回滚,但仍然可以提交事务。

如何让Spring不回滚事务?

最佳答案

设法为此问题创建了一个测试用例:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:web/WEB-INF/spring/applicationContext.xml",
        "file:web/WEB-INF/spring/services.xml"})
@Transactional
public class DoNotRollBackTest {
    @Autowired FakeService fakeService;

    @Test
    @Rollback(false)
    public void testRunXFireException() {
        fakeService.doSomeTransactionalStuff();
    }
}

伪造服务:

@Service
public class FakeService {
    @Autowired private EcomService ecomService;
    @Autowired private WebService webService;

    @Transactional(noRollbackFor={XFireRuntimeException.class})
    public void doSomeTransactionalStuff() {
        Order order = ecomService.findOrderById(459);

        try {
            webService.letsThrowAnException();
        } catch (XFireRuntimeException e) {
            System.err.println("Caugh XFireRuntimeException:" + e.getMessage());
        }

        order.setBookingType(BookingType.CAR_BOOKING);
        ecomService.persist(order);
    }
}

网络服务:

@Transactional(readOnly = true)
public class WebService {
    public void letsThrowAnException() {
        throw new XFireRuntimeException("test!");
    }
}

这将重新创建回滚异常。

然后我意识到该事务可能在 WebService.letsThrowAnException 中被标记为 rollbackOnly,因为 WebService 也是事务性的。我转到注释:

@Transactional(noRollbackFor={XFireRuntimeException.class})
    public void letsThrowAnException() {

现在事务没有被回滚,我可以将更改提交到 Order。

关于java - 如何防止 JPA 回滚事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1701750/

相关文章:

java - hibernate 映射: using same object multiple times

java - 在 Struts 1.3 中, Controller 用变量填充 View 的最佳方式是什么?

java - 如何从Java中的连接获取查询字符串?

java - 在添加到 jcomponent 的容器上绘制

java - 带有 { } 大括号的 Spring MVC @Path 变量

java - BCryptPasswordEncoder Spring Security 未定义

java - @Async 与 outstream 和 thread.sleep 方法

java - 增加 BufferedImage 的 PPI

java - 交易问题 : No Hibernate Session bound to thread

java - 使用 JPA2 Criteria API 查询字符串子集