无法在service中try catch 数据库异常的的解决方案

在批量数据导入时,为避免一条数据异常导致整个导入失败,通常使用try-catch捕获异常。将处理代码从Controller移到Service后,try-catch无法正常工作。经过调试发现,由于Hibernate未立即执行SQL,异常未抛出。解决方案是在saveOrUpdate()后添加baseDao.flush()来强制刷新session缓存,确保异常能被立即捕获。在Controller层,由于事务在service方法结束时才提交,所以在Service层需要手动触发flush()来实现异常捕获。
摘要由CSDN通过智能技术生成

 例如有一个批量操作数据库的功能(例如数据导入),当某条数据导入出现数据异常后,希望不影响后面数据的导入,于是我们通常情况会想到用try,catch将异常捕后,继续后面的处理;

 

本来的处理导入的代码是放在Ctroller层的,一直没出现什么问题,数据库异常正常捕获。但是近两天看Ctroller层中的代码太多涉及到业务逻辑的处理,于是进行优化,将导入的处理方法移到Service层,问题就出现了,处理数据库异常捕获的try ,catch失效了,该报异常还是报异常,数据一有错误,导入完全失败。

 

调试代码过程中,发现虽然saveOrUpdate()后并没有发出SQL语句,也就是没有真正执行持久化操作,因此异常还没抛出,当然也就无法捕获了,于是想办法让hibernate立即执行SQL,于是在saveorUpdate()后,加了句baseDao.flush()方法,刷新session缓存,oK,问题解决。

 

写道
public int importSendRecords(List<SendRecord> imports) {
SendRecord srd = null;
int failCount = 0;
SendRecord pRecord = null;
for (SendRecord record : imports) {
pRecord = findSendRecordIfExists(record);
if (pRecord == null) { //判断发行履历客户主表是否存在该客户
String tempCode = findMaxTmpSoldToCode();
record.setSoldToCode(tempCode);
srd = record;

} else {
srd = pRecord;
srd.setCapitalType(record.getCapitalType());
srd.setProfession(record.getProfession());
srd.setTelephone(record.getTelephone());
srd.setFax(record.getFax());
srd.setEmail(record.getEmail());
srd.setPostalCode(record.getPostalCode());
}

try {
baseDao.saveOrUpdate(srd);
baseDao.flush();
} catch (Exception e) {
failCount = failCount + srd.getSendRecordDetailList().size() + 1;
logger.error("发送履历导入过程中:[客户编号=" + srd.getSoldToCode() + "\t客户名称=" + srd.getCustomerNtvName()
+ " \t客户地址=" + srd.getNtvAddress() + "\t客户部门=" + srd.getDepartment() + "\t联系人="
+ srd.getAttention() + "]对应的【主记录】导入失败");
e.printStackTrace();
continue;
}

for (SendRecordDetail srdd : record.getSendRecordDetailList()) {
srdd.setSendRecord(srd);
srdd.setSendCode(constructSendCode());
try {
baseDao.saveOrUpdate(srdd);
baseDao.flush();
} catch (Exception e) {
failCount++;
logger.error("发送履历导入过程中:[客户编号=" + srd.getSoldToCode() + "客户名称=" + srd.getCustomerNtvName()
+ " 客户地址=" + srd.getNtvAddress() + "客户部门=" + srd.getDepartment() + "联系人="
+ srd.getAttention() + "]对应的【子记录】导入失败");
e.printStackTrace();
}

}

}

return failCount;

 

 

    回想之所以在Ctroller层,没有发生这种情况是因为,service方法执行完成后,事务就已经提交了,而在service层方法内部为保证事务的原子性,都是同步提交的,到service方法结束后才执行,因此try,catch中无法捕获数据库异常了,为了让它立刻执行,只有通过flush()刷新缓存了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值