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; package com.ruoyi.sip.service.impl;
import java.util.List; 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.exception.ServiceException;
import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.common.utils.ShiroUtils;
@ -22,7 +24,6 @@ public class AgentInfoServiceImpl implements IAgentInfoService
{ {
@Autowired @Autowired
private AgentInfoMapper agentInfoMapper; private AgentInfoMapper agentInfoMapper;
/** /**
* *
* *

View File

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

View File

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

View File

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