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