spring - 使用 Hibernate JPA 处理工作单元的问题
问题描述
我使用 Spring + Hibernate + JPA
我需要通过插入他们的订单来处理客户列表。
这是工作单元:
for(Customer customer: CustomerList) {
List<Order> orderList = customer.getOrders();
for(Order order: OrderList) {
//1. Insert order into ORDER table
//If insert fails due to Duplicate key then no rollback and I follow steps 2 & 3.
//If insert fails due to any reason except duplicate key then rollback all the previous transactions
//2. select the order record (If any issue during selection then rollbackall the previous transactions)
//3. Update the order If status of the order is different from that in DB (If any issue during update then rollback all the previous transactions)
}
// 4. Update Customer record into CUSTOMER table (If any issue during update then rollback all the previous transactions)
}
当所有订单和客户数据库流程都正常时,需要提交。
插入订单
1.a 如果重复订单不回滚。但是,如果 req 中的订单状态与 db 中的订单状态不同,则从表中选择该订单并更新
1.b 如果在插入 ORDER 过程中出现任何其他错误,则回滚
1.c 如果没有错误,则继续插入特定客户的订单
完成特定客户的订单后,更新客户表
循环继续..
在处理点 1、2 和 3 时,如果一切正常,则需要提交。如果中间有任何问题,那么所有事务都会回滚
Controller --> Facade 层 --> Service --> Repository/Dao
正面:
@Autowired
MyServiceBean serviceBean;
@Transactional(noRollbackFor = {EntityExistsException.class, PersistException.class, ConstraintViolationException.class, DataIntegrityViolationException.class})
@override
public void facadeMethod(MyReq req) {
List<Customer> custList = req.getCustomers():
for(Customer customer: CustList) {
List<Order> orderList = customer.getOrders();
for(Order order: orderList) {
String dbAction = "";
try {
dbAction = serviceBean.insertOrder(order);
} catch(Exception e) {
// log exception and roll back completely
}
if("handleDupl".equalsTo(dbAction) {
serviceBean.handleDuplOrder(order);
}
}
myService.updateCustomer(customer);
}
}
服务:
@Autowired
MyRepository repo;
@Transactional(propagation = propagation.REQUIRES_NEW)
@override
public String inserOrder() {
String dbAction = "";
try {
repo.insertOrderDao(order);
} catch(all duplicate key exceptions like entityExist, persist, ConstraintVioaltion, DataIntegrity e) {
dbAction = "handleDuplOrder";
} catch(all other Exception except duplicate key e) {
// roll back and throw exception to Facade layer
}
return dbAction;
}
@Transactional(propagation = propagation.REQUIRES_NEW)
@override
public void handleDuplOrder(Order order) {
try {
repo.selectOrderDao(order);
repo.updateOrder(order);
} catch(Exception e) {
// roll back and throw exception to Facade layer
}
}
存储库:
@PersistentContext(unitNmae = "MY_SHCEMA")
EntityManager entityManager;
@Override
public void insertOrderDao(Order order) {
entityManager.persist(order);
entityManager.flush();
}
问题:
当我向一个有单个订单的客户发送请求时,订单重复,我看到 PersistException 在 Service 方法中被捕获,当它从 Service 方法中存在时,它也会抛出 TransactionSystemException(嵌套异常是 RollbackException:事务被标记为仅回滚,无法提交 JPA 事务)被抛出到外观层,而不管我如何抑制内部事务中的异常。
如果我能以这种方式实现工作单元提交或回滚,请提出建议。
预期的:
我希望 Spring 的 @Transactional 通过不回滚并且不影响下一个事务来忽略重复键异常。
解决方案
您的外部事务仍然失败,因为您将其ApplicationDuplOrderException()
放入服务中。
您应该如下设置您的服务:
@Transactional
@Override
public void facadeMethod(MyReq req) {
List<Customer> custList = req.getCustomers():
for(Customer customer: CustList) {
List<Order> orderList = customer.getOrders();
for(Order order: orderList) {
try {
myService.insertOrder(order);
} catch(Exception e) {
// log exception and roll back completely
throw e; // important, you must rethrow
}
}
myService.updateCustomer(customer);
}
}
@Transactional(propagation = propagation.REQUIRES_NEW)
@Override
public void inserOrder() {
try {
repo.insertOrderDao(order);
} catch(all duplicate key exceptions like entityExist, persist, ConstraintVioaltion, DataIntegrity e) {
log.error(xxx); // instead of throwing
} catch(all other Exception except duplicate key e) {
throw e;
}
}
推荐阅读
- python - python的并发异步问题
- javascript - Bootstrap 4:当上面的部分关闭时关闭打开部分
- c++ - 按住键直到事件 C++
- python - 如何读取在记录的实际 JSON 字典部分之前具有整数值的数据文件?
- angular - chartjs-node-canvas 甜甜圈图
- ruby - 如何使用 Ruby-Vips 高效地创建纯色背景图像
- javascript - 如何通过 xpath 获取元素?
- amazon-web-services - 嘿,我如何才能看到为什么我的实时技能中的用户会出现后备意图?
- html - 如何使用 MathJax 在 Materialise 的工具提示中显示 Latex 公式?
- python - 自动播放 matplotlib FuncAnimation jsthml 元素