当前位置: 首页 > 面试题库 >

如何防止JPA回滚事务?

夹谷衡
2023-03-14
问题内容

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

包括struts(DelegatingActionProxy)和事务在内的所有内容都使用Spring进行配置。

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

有时,Web服务将引发未经检查的异常。我捕获了此异常并抛出了一个已检查的异常。我不希望事务回滚,因为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();
    }
}

FakeService:

@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。



 类似资料:
  • 我有一个由Spring框架维护的对象,我使用注释将它注入到我想要的任何DAO类中,如下所示。 我使用那些DAO类在数据库中保存如下内容。 现在,这里的两个DAO都使用了通过注入的相同的。现在,如果在之后发生异常,那么我甚至希望回滚保存的实体。但是,如何从中获取? 如果所有DAO都持有相同的对象,那么我可以直接调用类的方法吗?返回新事务或当前与关联的任何事务吗?

  • 我们的编写器设计用于将记录写入关系数据库。如果任何记录发生异常,Spring Batch将对区块中的每条记录执行回滚并重试写入操作。这导致发生SQL重复密钥异常,因为区块中先前处理的记录已成功写入数据库。 我们已经尝试使用noRetry()和noRollback(),明确指定不应该触发重试或回滚的异常列表。 根据Spring Batch在线留档noRollback()可用于防止在ItemWrite

  • 我有一个记录表Table1 这里,我想将F1 Varchar的数据类型更改为Decimal(3,0);然后,我创建一个具有新结构的新表。 我想通过显式地将varchar转换为decimal,将旧表的每个recod插入到new中。所以我在try catch块中写了这个命令。如果产生了错误,那么在catch块中我可以用它的默认值填充它。但是整个工作是在begin transaction和commit

  • 问题内容: 在IE上,我可以使用(非常不标准,但可以正常工作)的jQuery做到这一点 但是,是否可以以在Firefox上运行的方式或以跨浏览器的方式获得奖励呢? 作为记录: 什么也没做。 解决了问题,但使退格键在页面上不可用,这甚至比原始行为还差。 编辑:我这样做的原因是我不是在创建一个简单的网页而是一个大型应用程序。仅仅因为您在错误的位置按了退格键,就失去了10分钟的工作,这真是令人讨厌。通过

  • 尽管捕获了RuntimeException并声明了noRollbackFor属性,但事务总是回滚。有什么解释吗?? 日志跟踪信息: