最近在项目开发遇到oracle数据库中的数据计算不一致的问题,同时这个问题还涉及到线程同步的问题,这里方法中解决同步的问题使用了synchronized关键字实现同步,但是在这个方法中计数时还是导致了计数不准确问题,最后发现问题是oracle更新数据是需要手动提交的,导致了同步方法了但事务没一起同步导致了数据不一致的问题,伪代码如下:
private synchronized boolean counterManage(Parameter param) { String bookNo = param.getBookNo(); String goodsRegNo = parameter.getGoodsRegNo(); Float count = param.getCount(); Float total; CounterDetail counterDetail = CounterDAO.getInstance().findCounterByGoodsRegNo(goodsRegNo, counterNo); if(counterDetail != null && counterDetail.getEnableStatus() == 0) { total = count + counterDetail.getgStock(); counterDetail .setgStock(total); CounterDAO.getInstance().updateBookDetail(counterDetail .getId(), total, 0); } else { counterDetail = new CounterDetail(); counterDetail .setBookNo(bookNo); counterDetail .setGoodsRegNo(goodsRegNo); counterDetail .setEnableStatus(0); counterDetail .setgStock(count); counterDetail .setgName(param.getgName()); counterDetail .setgModel(param.getgModel()); counterDetail .setUnitCode(param.getUnitcode()); CounterDAO.getInstance().saveBookDetail(counterDetail ); } //session.commit(); return true; }
代码2
public boolean counterService(Object obj) { //其他代码
counterManage(Parameter param);
session.commit();
}
上面红色部分提交经过封装后提交方法中所有未提交的事务,在代码2中session.commit();可以同时提交counterManage()方法中未提交的事务,但是在这里提交会导致虽然counterManage方法已同步,但是对于更新方法时一个线程进入调用同一个对象之后就会出现读脏数据导致数据的不一致性。目前解决方案是方法counterManage()执行完就提交。
如有更好的方法请给出评论共同进步,谢谢!