我面临下面的问题 - 无法在Performance或更低的环境中重现它,但只有在Prod使得调试有点困难,因此如果我能得到一些线索在这里发布。 试图让它尽可能短,但仍然很长..
问题: 在两步订单创建过程中,即创建客户+提交订单 - 我们将获得唯一约束违规,其中单个客户ID被分配给在多个位置创建的订单。
不确定哪里出错了。 我找不到的东西很少
Pom Entry如下所示,Spring / Hibernate堆栈的版本,数据库是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);
我不确定以下代码中的某些内容是否在线程处理点出现错误
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;
}
日志显示在第2循环和第2循环中打印相同的客户ID。 Loop3在具有不同线程的多个实例中
在customer.setEmail的Loop3结束时出现空指针
Dao Code如下
@SuppressWarnings("unchecked")
@Override
public Customer addUpdateCustomer(Customer customer)
throws InternalDataAccessException {
if (customer.getId() != null && customer.getId() != 0)
saveMerge(customer);
else
save(customer);
return customer;
}
如果您觉得代码的其他部分可以为此问题增加清晰度,请告诉我。
答案 0 :(得分:0)
此问题最终成为业务案例场景问题,并在整个创建客户流程移至Oracle DB中的存储产品时得到解决
我们有一个Table Cust #Reinquished从一个Range中取出Active Customer No,如果消耗了它们,则设置一些新的范围或者增加no并执行SaveMerge()
这3个Hibernate查询步骤已更改为One Stored Proc,它运行正常。