refactor(sip-service): 添加线程安全锁以确保编码生成操作的线程安全性在 `AgentInfoServiceImpl`, `CustomerInfoServiceImpl`, `PartnerInfoServiceImpl` 和 `VendorInfoServiceImpl` 中添加了 `ReentrantLock`以确保生成编码的操作是线程安全的。具体修改包括:
- 在每个服务实现类中引入 `Lock` 和 `ReentrantLock`。- 在插入和更新操作中使用锁来保证编码生成的唯一性。
- 在 `ProjectOrderInfoMapper.xml` 中修正了一个 SQL 语句的格式问题。

这些改动有助于避免多线程环境下可能发生的编码冲突问题。
```
dev_1.0.0
chenhao 2025-09-11 15:50:16 +08:00
parent c688decad4
commit 3c58f9f254
5 changed files with 98 additions and 42 deletions

View File

@ -1,6 +1,8 @@
package com.ruoyi.sip.service.impl;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.ShiroUtils;
@ -22,7 +24,6 @@ public class AgentInfoServiceImpl implements IAgentInfoService
{
@Autowired
private AgentInfoMapper agentInfoMapper;
/**
*
*

View File

@ -1,6 +1,8 @@
package com.ruoyi.sip.service.impl;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.exception.ServiceException;
@ -29,6 +31,8 @@ public class CustomerInfoServiceImpl implements ICustomerInfoService
private CustomerInfoMapper customerInfoMapper;
@Autowired
private ICnareaService cnareaService;
// 添加静态锁,确保生成编码的操作是线程安全的
private static final Lock lock = new ReentrantLock();
/**
*
*
@ -63,12 +67,18 @@ public class CustomerInfoServiceImpl implements ICustomerInfoService
public int insertCustomerInfo(CustomerInfo customerInfo)
{
customerInfo.setCreateBy(ShiroUtils.getUserId().toString());
lock.lock();
try {
customerInfo.setCustomerCode(generateCode(customerInfo.getProvince()));
int i = customerInfoMapper.selectCountByCode(customerInfo);
if (i > 0) {
throw new ServiceException("客户编码已存在");
}
return customerInfoMapper.insertCustomerInfo(customerInfo);
} finally {
lock.unlock();
}
}
private String generateCode(String province) {
@ -120,6 +130,8 @@ public class CustomerInfoServiceImpl implements ICustomerInfoService
// 如果省份发生变化,需要重新生成客户编码
CustomerInfo oldCustomerInfo = customerInfoMapper.selectCustomerInfoById(customerInfo.getId());
if (oldCustomerInfo != null && !oldCustomerInfo.getProvince().equals(customerInfo.getProvince())) {
lock.lock();
try {
String newCustomerCode = generateCode(customerInfo.getProvince());
customerInfo.setCustomerCode(newCustomerCode);
@ -130,6 +142,11 @@ public class CustomerInfoServiceImpl implements ICustomerInfoService
if (count > 0) {
throw new ServiceException("客户编码已存在");
}
return customerInfoMapper.updateCustomerInfo(customerInfo);
} finally {
lock.unlock();
}
}
return customerInfoMapper.updateCustomerInfo(customerInfo);

View File

@ -2,6 +2,7 @@ package com.ruoyi.sip.service.impl;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@ -32,6 +33,9 @@ public class PartnerInfoServiceImpl implements IPartnerInfoService
private PartnerInfoMapper partnerInfoMapper;
@Autowired
private ICnareaService cnareaService;
// 添加静态锁,确保生成编码的操作是线程安全的
private static final Lock lock = new ReentrantLock();
/**
*
*
@ -74,6 +78,9 @@ public class PartnerInfoServiceImpl implements IPartnerInfoService
public int insertPartnerInfo(PartnerInfo partnerInfo)
{
partnerInfo.setCreateBy(ShiroUtils.getUserId().toString());
// 生成编码时加锁,确保线程安全
lock.lock();
try {
//生成编码
partnerInfo.setPartnerCode(generateCode(partnerInfo.getProvince()));
@ -82,6 +89,9 @@ public class PartnerInfoServiceImpl implements IPartnerInfoService
throw new ServiceException("该编码已存在");
}
return partnerInfoMapper.insertPartnerInfo(partnerInfo);
} finally {
lock.unlock();
}
}
private String generateCode(String province) {
@ -120,14 +130,22 @@ public class PartnerInfoServiceImpl implements IPartnerInfoService
// 如果省份发生变化,需要重新生成客户编码
PartnerInfo existsInfo = partnerInfoMapper.selectPartnerInfoById(partnerInfo.getId());
if (existsInfo != null && !existsInfo.getProvince().equals(partnerInfo.getProvince())) {
// 重新生成编码时加锁,确保线程安全
lock.lock();
try {
String newPartnerCode = generateCode(partnerInfo.getProvince());
partnerInfo.setPartnerCode(newPartnerCode);
}
int i = partnerInfoMapper.selectCountByCode(partnerInfo);
if (i > 0) {
throw new ServiceException("该编码已存在");
}
return partnerInfoMapper.updatePartnerInfo(partnerInfo);
} finally {
lock.unlock();
}
}
return partnerInfoMapper.updatePartnerInfo(partnerInfo);
}
/**

View File

@ -1,6 +1,9 @@
package com.ruoyi.sip.service.impl;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import cn.hutool.core.collection.CollUtil;
@ -32,7 +35,8 @@ public class VendorInfoServiceImpl implements IVendorInfoService {
private VendorInfoMapper vendorInfoMapper;
@Autowired
private IOmsWarehouseInfoService warehouseInfoService;
// 添加静态锁,确保生成编码的操作是线程安全的
private static final Lock lock = new ReentrantLock();
/**
*
*
@ -63,11 +67,20 @@ public class VendorInfoServiceImpl implements IVendorInfoService {
*/
@Override
public int insertVendorInfo(VendorInfo vendorInfo) {
lock.lock();
try {
checkUnqCode(vendorInfo);
vendorInfo.setVendorStatus(VendorInfo.VendorStatusEnum.NORMAL.getCode());
vendorInfo.setCreateTime(DateUtils.getNowDate());
vendorInfo.setCreateBy(ShiroUtils.getUserId().toString());
return vendorInfoMapper.insertVendorInfo(vendorInfo);
} catch (Exception e) {
throw new ServiceException("保存超时,请重试");
} finally {
lock.unlock();
}
}
private void checkUnqCode(VendorInfo vendorInfo) {
@ -91,10 +104,17 @@ public class VendorInfoServiceImpl implements IVendorInfoService {
*/
@Override
public int updateVendorInfo(VendorInfo vendorInfo) {
lock.lock();
try {
checkUnqCode(vendorInfo);
vendorInfo.setUpdateTime(DateUtils.getNowDate());
vendorInfo.setUpdateBy(ShiroUtils.getUserId().toString());
return vendorInfoMapper.updateVendorInfo(vendorInfo);
} catch (Exception e) {
throw new ServiceException("保存超时,请重试");
} finally {
lock.unlock();
}
}
/**