英文:
How to partially rollback data in spring boot, errors to be persited
问题
我在事务中有一系列表数据创建操作,使用springboot
,java
,jpa
和hibernate
,序列如下所示。所使用的数据库是Oracle
。
- 下订单 - 插入到order_details_table表
- 处理付款 - 插入到payment_info表
- 错误消息(信息,警告,错误) - 插入到error_message表
如果在处理请求期间出现任何错误(信息,警告,错误),我会将错误消息插入到error_message
表中。我的信息和警告消息会在没有错误发生时持久保存到error_message
中。
但是,如果出现错误,我会从代码中抛出错误以回滚transaction
,虽然它能够运行,但是我的error_message
也会被回滚。
我想要回滚details_table
和payment_info
,但不回滚error_message
,我希望它们能够被持久化。
我如何实现相同的效果?
英文:
I have sequence of table data creation in transaction, using springboot
, java
, jpa
and hibernate
sequence shown below. Database used is Oracle
- Place order - insert into order details_table
- Process Payment - insert into payment_info table
- Error Message(info, warning, error) - insert into error_message table
I am inserting error messages in error_message
table if any error occurs(info, warning, error).<br/>
My info and warning message get persisted into error_message
if no error occurs during the processing of the request.
But if there is an error, I am throwing an error from code to rollback the transaction
, its working but my error_message
also get rollback.
I want to rollback details_table
and payment_info
but not the error_message
, I want them to be persisted.
How I can achieve the same?
答案1
得分: 1
使用两个不同的事务。
默认的事务传播方式是REQUIRED
,当在没有事务上下文的情况下调用带有@Transactional
注解的方法时,将会启动一个新的事务,但如果已经存在事务,则会加入该事务,最终形成一个单一事务。如果发生回滚,所有操作将会回滚,因为它们属于同一个事务。
将事务传播方式更改为REQUIRES_NEW
,以始终强制启动新事务(而不是加入已存在的事务)。这将允许您独立于付款信息提交错误消息事务。
@Transactional
public void placeOrder(Order oder) {
// 处理订单
paymentGateway.processPayment();
// 保存订单 <- 这里的异常会回滚当前事务,但不会影响PaymentGateway中的事务,因为它是独立的
}
// 在PaymentGateway中
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void processPayment() {
// 处理付款
// 插入错误消息
}
进一步阅读:了解PROPAGATION_REQUIRED。确保您还理解异常如何影响事务。
英文:
Use two different transactions.
The default transaction propagation is REQUIRED
, when calling your @Transactional
annotated method without a transactional context, a new transaction will be started but if there's already a transaction in place, the transaction will be joined, ending up with a single transaction. In case of rollback, all operations will be rollbacked as they belong to the same transaction.
Change the transaction propagation to REQUIRES_NEW
in order to always force starting a new transaction (instead of joining it if there's one). This will allow you to commit the error messages transaction independently from the payment info.
@Transactional
public void placeOrder(Order oder) {
// process order
paymentGateway.processPayment();
// save order <- an exception here will rollback the current
// transaction but not the one in PaymentGateway which is independent
}
// In PaymentGateway
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void processPayment() {
// process payment
// insert error messages
}
Further reading: Understanding PROPAGATION_REQUIRED. Make sure you also understand how exceptions affect transactions.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论