使用Hibernate JPA处理工作单元中的问题 [英] Problem in Handling Unit of work using Hibernate JPA

查看:125
本文介绍了使用Hibernate JPA处理工作单元中的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Spring + Hibernate + JPA

I use Spring + Hibernate + JPA

我需要通过插入客户订单来处理客户列表.

I need to handle the list of customers by inserting their orders.

这是工作单位:

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)
}

当所有订单和客户数据库流程都正常时,需要提交.

Commit is required when all the orders and customer db processes are ok.

  1. 插入订单

  1. Insert order

1.a如果重复订购,请不要回退.但是从表中选择该顺序,并在请求中的顺序状态与db中的顺序不同时进行更新

1.a If duplicate order do not roll back. But select that order from table and update if the status of the order is different in the req compared to the one in db

1.b如果在插入ORDER期间出现任何其他错误,则回滚

1.b If any other error during inserting of ORDER then roll back

1.c如果没有错误,则继续插入特定客户的订单

1.c If no error then proceed inserting orders of the particular Customer

完成特定客户的订单后,然后更新客户表

Once orders of the particular Customer is done, then update Customer table

循环继续..

处理点1、2和3时,如果一切正常,则需要提交. 如果中间出现任何问题,则会回滚所有交易

While handling point 1, 2 and 3 If everything is ok, then commit is required. If any issues in the middle then all transactions are rolled back

控制器->外观层->服务->存储库/Dao

Controller --> Facade layer --> 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方法中存在PersistException时,它还会引发TransactionSystemException(嵌套异常为RollbackException:事务标记为无论如何回滚,都无法提交JPA事务),无论我如何抑制内部事务中的异常,都被扔到Facade层.

When I send req with One customer who has single order, where the order is duplicate, I see PersistException is caught inside Service method and when it exists from Service method it also throws TransactionSystemException(nested exception is RollbackException: Transaction is marked as rollback only, could not commit JPA transaction) is thrown to Facade layer irrespective of the how I suppress the exception in inner transaction.

请告知我是否可以通过这种方式实现工作单元的提交或回滚.

Kindly advice If I can achieve Unit of work commit or rollback in this way.

预期:

我希望Spring的@Transactional通过不回滚并且不影响下一个事务来忽略重复的键异常.

I want Spring's @Transactional to ignore Duplicate key exceptions by not rolling back and not affecting the next transaction.

推荐答案

您的外部事务仍然失败,因为您在服务中抛出了ApplicationDuplOrderException().

Your outer transaction still fail because you throw ApplicationDuplOrderException() inside your service.

您应按以下步骤设置服务:

You should setup your services like below:

@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; 
  }
}

这篇关于使用Hibernate JPA处理工作单元中的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆