我写了一个任务调度程序作业,每30分钟为合格的患者生成帐单。在这里,我很困惑,我按照标准保留的传播和隔离级别是否正确。我应该始终将REQUIRES_NEW用作传播的一部分吗?
以下部分的任何建议。
private void startBilling() throws Exception {
List<Integer> patientIds = null;
try {
patientIds = getPatientsForBilling();
if(null != patientIds) {
for(Integer patient : patientIds) {
updatePatientDetails(patient, "STARTED", jdbcTemplate);
makeBillForPatient(patient, jdbcTemplate);
updatePatientDetails(patient, "COMPLETED", jdbcTemplate);
}
}
} catch (Exception e) {
//LOG HERE
updatePatientDetails(patient, "TERMINATED", jdbcTemplate);
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class,isolation = Isolation.SERIALIZABLE)
private void makeBillForPatient(Integer patient, JdbcTemplate jdbcTemplate2) {
// A bill for the patient will be generated and printed
}
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class,isolation = Isolation.SERIALIZABLE)
private void updatePatientDetails(Integer patient,
String status, JdbcTemplate jdbcTemplate) {
// Update the patient billing status STARTED
}
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class,isolation = Isolation.SERIALIZABLE)
private List<Integer> getPatientsForBilling() {
return new ArrayList<Integer>();
}
这是我已经实现的逻辑
任何想法都将不胜感激。
答案 0 :(得分:0)
实际上,这取决于您的逻辑。据我了解,您将患者标记为“已开始”,然后执行一些可能会长时间运行的复杂任务(创建清单),然后释放患者。
应该将这些动作隔离开来,以便您需要为每个动作单独进行事务处理,在这种情况下,REQUIRES_NEW是可以的。
但是您的逻辑(显示在发布的代码中)有一些泄漏。
想象一下makeBillForPatient()方法调用将引发异常。您遇到的麻烦:
患者卡在STARTED状态。您需要以某种方式处理保持“开始”状态的患者以重设他们。
所有其余患者均未得到处理,因为发生异常时您退出了循环。
这样的代码
patientIds = getPatientsForBilling();
if(null != patientIds) {
for(Integer patient : patientIds) {
try {
updatePatientDetails(patient, "STARTED", jdbcTemplate);
try {
makeBillForPatient(patient, jdbcTemplate);
updatePatientDetails(patient, "COMPLETED", jdbcTemplate);
} catch (Exception e) {
//print something in the log here and reset patient status
updatePatientDetails(patient, "INITIAL", jdbcTemplate);
}
} catch (Exception e) {
//print something in the log here
}
}
}
也不要留下空的捕获块。如果出现问题,很难找到源。至少在日志中打印一些内容。