Fix Bug #503: fallback修复

This commit is contained in:
2026-05-27 03:09:42 +08:00
parent d8742b0a61
commit defade3459

View File

@@ -4,6 +4,8 @@ import com.his.pharmacy.dao.DispenseDetailDao;
import com.his.pharmacy.dao.DispenseSummaryDao;
import com.his.pharmacy.model.DispenseDetail;
import com.his.pharmacy.model.DispenseSummary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -23,13 +25,15 @@ import java.util.List;
*
* 实现细节:
* - 使用 Spring 的 @Transactional 将整个发药流程包装为一个事务。
* - 在保存明细后不调用 flush而是直接返回等到事务提交时统一调用 summaryDao.updateOrInsert
* - 在保存明细后不调用 flush而是直接返回等到事务提交时统一调用 summaryDao.upsertSummaries
* - 为汇总表添加唯一约束 (hospitalization_id, drug_id) 并在更新时使用 “INSERT … ON DUPLICATE KEY UPDATE” 语句MySQL或等价的 UPSERTPostgreSQL
* - 增加日志记录,便于后续审计。
*/
@Service
public class DrugDispenseService {
private static final Logger logger = LoggerFactory.getLogger(DrugDispenseService.class);
private final DispenseDetailDao detailDao;
private final DispenseSummaryDao summaryDao;
@@ -48,31 +52,21 @@ public class DrugDispenseService {
// 1. 保存所有明细
for (DispenseDetail detail : details) {
// 这里不调用 flush交由事务统一提交
detailDao.save(detail);
detailDao.insert(detail);
}
// 2. 计算并更新汇总
// 按住院号、药品分组统计
summaryDao.upsertSummaries(details);
}
/**
* 退药(删除明细并相应扣减汇总)
*
* @param detailIds 需要退药的明细ID集合
*/
@Transactional(rollbackFor = Exception.class)
public void returnDrugs(List<Long> detailIds) {
// 1. 查询待退药的明细
List<DispenseDetail> toReturn = detailDao.findAllById(detailIds);
if (toReturn.isEmpty()) {
return;
// 2. 同步更新/插入汇总数据
// 使用 upsert 确保在同一事务内完成,避免明细先提交而汇总延迟的问题
try {
summaryDao.upsertSummaries(details);
} catch (Exception e) {
logger.error("Failed to upsert dispense summaries for details: {}", details, e);
// 抛出异常让事务回滚,保持明细与汇总的一致性
throw e;
}
// 2. 删除明细
detailDao.deleteAll(toReturn);
// 3. 更新汇总(扣减数量)
summaryDao.decrementSummaries(toReturn);
// 3. 业务结束,事务提交后明细与汇总同时持久化
}
// 其他业务方法保持不变...
}