繁体   English   中英

这可能是Java线程还是Hibernate问题?

[英]Could this be a Java threading or Hibernate Issue?

我面临以下问题-无法在Performance或较低环境中重现它,但仅在Prod中使调试变得有点困难,因此,如果我能得到一些线索,请在此处发布。 试图使它尽可能短,但仍然很长。


问题 :在2个步骤的订单创建过程中,即创建客户+提交订单-我们将收到唯一约束违规,其中单个客户ID被分配给在多个位置创建的订单。

不知道哪里出了问题。 我找不到的一些东西

  1. Oracle在生成序列方面是独一无二的
  2. Hibernate的默认分配大小为50,并且在分发这50个序列方面进行了优化
  3. 这让我感到很奇怪,也许有一些线程在实体复制发生在某处附近劫持了这个序列,大约在下面的最后两种方法周围。

对于Spring / Hibernate堆栈版本,Pom Entry如下所示,数据库为Oracle

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>3.2.1.RELEASE</spring.version>
        <hibernate.version>4.1.10.Final</hibernate.version>
        <thymeleaf.version>2.1.0.RELEASE</thymeleaf.version>
        <tiles.version>2.2.2</tiles.version>
    </properties>

客户对象如下

@Entity
@Table(name = "CUSTOMER")
public class Customer implements Serializable {
    private static final long serialVersionUID = 1L;

    @SequenceGenerator(name="CUSTOMER_SEQUENCE_GENERATOR", 
        sequenceName="CUSTOMER_SEQ", allocationSize = 1)

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, 
        generator="CUSTOMER_SEQUENCE_GENERATOR")
    @Column(name = "CUSTOMER_ID", unique = true, nullable = false)
    private Integer id;

可以从3个控制器和2个服务方法等不同地方调用此代码段-可以在整个代码中说。

 Customer customer = createCustomerEntity(newcustomer);
 customer = customerManagementDAO.addUpdateCustomer(customer);

以下是2种方法的详细信息

从线程的角度来看,我不确定以下代码中的某些内容是否出现错误

    private Customer createCustomerEntity(CustomerBean newcustomer) 
                 throws InternalBusinessException {
          Customer customer = null;
            try{
            // If Loop1
            if(newcustomer.getInternalcustomerid() == null){
                 customer = new Customer();
              customer.setCustomerNumber(newcustomer.getExternalSystemCustomerid());
            }
            // If Loop2
            if(newcustomer.getInternalcustomerid() != null){
                //if a new customer going for new  enrollment , 
                // we lookup up the customer in DB based on 
                // InternalCustomerId and merge the customer.
                Integer customerIdInternal = null;
                // Below Call goes to Internal Database to find existing Customer
                Customer customerEntity  = orderManagementDAO.findExistingCustomerByCustomerId(
                                newcustomer.getEoecustomerid().toString());
                if(customerEntity != null){
                customer = new Customer();  
                customer.setCustomerNumber(
                                newcustomer.getExternalSystemCustomerid()); 
                customerIdInternal = customerEntity.getId();
                if (customerIdInternal != null) {
                     customer.setId(customerIdInternal);
                }
            }
            //In case of customer look up if customer with same 
            // External System's id exists we merge the same customer.
            // If Loop3
if(newcustomer.getExternalSystemCustomerid() != null) {   
                // Below call goes to external System to find existing Customer Number
                Customer customerEntity = orderManagementDAO.findExistingCustomerByCustomerNumber(
                                newcustomer.getExternalSystemCustomerid().trim());
                Integer customerIdInternal = null;
                if(customerEntity != null) {
                    customer = new Customer();
                    customer.setCustomerNumber(
                                newcustomer.getExternalSystemCustomerid());
                    customerIdInternal = customerEntity.getId();
                 }
                if (customerIdInternal != null) {
                    customer.setId(customerIdInternal);
                }            
            }
            // End of If loop3
            customer.setEmail(newcustomer.getEmail()); //<== We have null pointers at this point in logs
            customer.setFirstName(newcustomer.getFirstname());
            customer.setLastName(newcustomer.getLastname());

            } catch (RuntimeException e) {
                throw new InternalBusinessException("createCustomerEntityForEOE failed", e);
            }
            return customer;
        }
  • 日志显示在具有不同线程的服务器实例中在Loop 2和Loop3中打印相同的客户ID

  • Null指针位于customer.setEmail的Loop3末尾

道代码如下

@SuppressWarnings("unchecked")
    @Override
    public Customer addUpdateCustomer(Customer customer) 
            throws InternalDataAccessException {
        if (customer.getId() != null && customer.getId() != 0)
            saveMerge(customer);
        else
            save(customer);
        return customer;
    }

如果您认为代码的其他部分可以使此问题更加清楚,请告诉我。

该问题最终更多地是业务案例方案问题,并且当整个create Customer流程移至Oracle DB中的存储产品时,该问题已解决。

我们放弃了表Cust#,以从范围中提取有效客户编号,如果消耗了它们,则执行一些步骤来设置新范围,或者增加否并执行SaveMerge()

这3个Hibernate查询步骤已更改为One Stored Proc,并且工作正常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM