写接口的时候,如果是数据库模式,经常会需要从对方数据库中直接提取数据,然后稍做处理,插入wms数据库,此时,一般就会在manager中既用到hibernate又用到jdbc,伪代码如下:其中接口getErpCompanyRowData方法是加了@Transactional的。
/**处理单条客户信息*/
1 public void getErpCompanyRowData(ResultSet rs, PreparedStatement ps,
Connection erp_con) throws SQLException {
2 ErpCompany ec = EntityFactory.getEntity(ErpCompany.class);
3 ec.setDownId(rs.getLong("downid"));
4 ec.setType(rs.getString("type"));
5 ec.setCompanyId(rs.getLong("companyid"));
6 ………可能很多set
7 commonDao.store(ec);
8
9 String sql = "update WMS_TRANSFERS_D_COMPANY set tranflag=1, downtime=?
where downid=?";
10 ps = erp_con.prepareStatement(sql);
11 ps.setTimestamp(1, Timestamp.valueOf(DateUtil.getDateTime()));
12 ps.setObject(2, ec.getDownId(), Types.BIGINT);
13 ps.executeUpdate();
14 erp_con.commit();
15}
此时,如果第9行的sql执行异常,可能的结果就是wms保存了ErpCompany,但是erp的表记录没有
更新成功,出现事务不一致,既然加了@Transactional,为什么会出现这种情况?
原来,Spring配置的@Transactional只有碰到运行时异常RuntimeException才会回滚,这个方法
抛出的是SQLException,SQLException没有继承RuntimeException,所以Spring的事务提交了,
但是jdbc的事务失败了,造成事务不一致。
如何解决?在接口中配置@Transactional(rollbackFor=Exception.class),让Spring遇到Exception
就回滚,这样即可保证事务一致。