Browse Source

物料属性导入bug

master
han\hanst 3 days ago
parent
commit
6f142dc62e
  1. 56
      src/main/java/com/gaotao/modules/warehouse/service/impl/IfsInventoryInitServiceImpl.java

56
src/main/java/com/gaotao/modules/warehouse/service/impl/IfsInventoryInitServiceImpl.java

@ -22,8 +22,11 @@ import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.TransactionTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
@ -60,6 +63,9 @@ public class IfsInventoryInitServiceImpl implements IfsInventoryInitService {
@Autowired
private PartAttributeMapper partAttributeMapper;
@Autowired
private PlatformTransactionManager transactionManager;
@Override
public PageUtils getInventoryStockList(InventoryStock data) {
IPage<InventoryStock> ipage = warehouseMapper.getIfsInventoryStockList(
@ -967,7 +973,11 @@ public class IfsInventoryInitServiceImpl implements IfsInventoryInitService {
log.warn("=== IFS库存Excel写入失败,已标记整批回滚 === 失败行: {}", rowNumber);
return buildImportAbortResult(errorMessages);
}
}
// 全部库存行写入成功后再补充属性,避免后续库存行失败时提前提交属性。
for (Map<String, Object> rowData : successList) {
int rowNumber = (int) rowData.get("rowNumber");
PartAttribute partAttribute = (PartAttribute) rowData.get("part_attribute");
if (partAttribute != null) {
try {
@ -1046,42 +1056,30 @@ public class IfsInventoryInitServiceImpl implements IfsInventoryInitService {
/**
* 插入part_attribute记录(如果不存在)。
* 已存在则跳过。插入失败先回滚到保存点再抛出,由调用方记日志后继续,不能把库存导入事务标成回滚。
* 已存在则跳过。查询与插入使用独立事务,失败仅回滚属性事务,由调用方记日志后继续。
*
* @param partAttribute 料件属性对象
* @return true=成功插入,false=已存在跳过
*/
private boolean insertPartAttributeIfNotExists(PartAttribute partAttribute) {
PartAttribute existing = partAttributeMapper.getPartAttributeByHeight(
partAttribute.getSite(), partAttribute.getPartNo(), partAttribute.getHeight());
if (existing != null) {
log.debug("料件属性已存在,跳过: site={}, partNo={}",
partAttribute.getSite(), partAttribute.getPartNo());
return false;
}
// JpaTransactionManager 不支持当前 JPA 方言的保存点,不能使用 NESTED/createSavepoint。
// REQUIRES_NEW 挂起库存事务,确保查询、插入及提交失败都不会污染库存事务。
TransactionTemplate attributeTransaction = new TransactionTemplate(transactionManager);
attributeTransaction.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
return Boolean.TRUE.equals(attributeTransaction.execute(status -> {
PartAttribute existing = partAttributeMapper.getPartAttributeByHeight(
partAttribute.getSite(), partAttribute.getPartNo(), partAttribute.getHeight());
if (existing != null) {
log.debug("料件属性已存在,跳过: site={}, partNo={}",
partAttribute.getSite(), partAttribute.getPartNo());
return false;
}
// SQL Server 主键冲突只中止当前语句,但连接上的事务可能无法再提交。
// 保存点把失败限制在这次属性插入,回滚后库存导入仍可继续。
Object savepoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
try {
partAttributeMapper.insert(partAttribute);
} catch (Exception e) {
try {
TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savepoint);
} catch (Exception rollbackEx) {
log.error("料件属性保存点回滚失败: site={}, partNo={}",
partAttribute.getSite(), partAttribute.getPartNo(), rollbackEx);
}
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
throw new RuntimeException(e);
}
TransactionAspectSupport.currentTransactionStatus().releaseSavepoint(savepoint);
log.debug("料件属性新增成功: site={}, partNo={}",
partAttribute.getSite(), partAttribute.getPartNo());
return true;
log.debug("料件属性新增成功: site={}, partNo={}",
partAttribute.getSite(), partAttribute.getPartNo());
return true;
}));
}
/**

Loading…
Cancel
Save