JPA执行SQL(主从添加)不提交事务问题

xiaoxiao2021-02-28  23

前段时间做项目遇到了一个问题,这里总结一下 环境 需要添加合同主表信息与从表信息(从表中需要存储主表id),因为bean在另一个项目中,但是却公用数据库,所以我们不能使用jpa 的save(对象) 方法。只能写sql,然后调用对应的createNativeQuery的方法。问题出现了。。。 因为是在service中处理,service的一个方法因为事务的原因将整个方法都走完才commit 坑爹的来了 。。。我先添加主表信息,然后再倒序查询主表,获取id 赋值给从表,但是无论如何我获取的都是上一个主表记录的id 但是控制台已经显示执行了主表插入的sql….就是因为事务的原因 他并没有commit 所以也没有id 解决办法 1.首先我尝试将主从添加写到两个service中,但是因为项目逻辑的原因 他们都需要在另外一个serivice中调用,所以还是在一个事务里面没有提交 2.我后来想到了flush 和 refresh 同步缓存和数据库 ,让他强制提交,最终呢还是不行 3.(真正的解决办法) 最终我才用JdbcTemplate 问题轻松解决

List<TContact2> contracts = this.supplierInfoWebServiceDao.search2(TContact2.class,"select * from contactbuy where id = "+id); if(null==contracts){ throw new BusinessException("获取合同信息出错"); } if(contracts.size()>0){ final TContact2 contract = contracts.get(0); KeyHolder keyHolder = new GeneratedKeyHolder(); dao.getJdbcTemplate().update(new PreparedStatementCreator() { public PreparedStatement createPreparedStatement(Connection con) throws SQLException { StringBuffer sbMain = new StringBuffer(""); sbMain.append("INSERT INTO mxinterface_purchasecontract "); sbMain.append("(contactcode,contractName,contractTotalMoney,projectDepartmentCode,projectDepartmentName,returnMessage,returnTime,success,supplcode,supplname) "); sbMain.append("values(?,?,?,?,?,?,?,?,?,?)"); PreparedStatement ps = con.prepareStatement(sbMain.toString(), Statement.RETURN_GENERATED_KEYS); ps.setString(1, contract.getContactcode()); ps.setString(2, contract.getContractName()); ps.setString(3, contract.getContractTotalMoney()); ps.setString(4, contract.getProjectInterfaceCode()); ps.setString(5, contract.getPurchaseDeptName()); ps.setString(6, ""); // ps.setString(7, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); ps.setString(7, null); ps.setString(8, "0"); ps.setString(9, contract.getSupplcode()); ps.setString(10, contract.getSupplname()); return ps; } }, keyHolder); // 主表ID final int approveID = Integer.valueOf(keyHolder.getKeyList().get(0).get("GENERATED_KEY").toString()); List<TContactDetail2> contractDetails = this.supplierInfoWebServiceDao.search2(TContactDetail2.class,"select * from contactbuydetail where contactid = "+id); if(null!=contractDetails&&contractDetails.size()>0){ for(TContactDetail2 detail:contractDetails){ String sql = "INSERT INTO mxInterface_purchaseContractDetail VALUES(NULL,"+approveID+"," + "'"+detail.getContactwzcode()+"','"+detail.getContactwzdetail()+"','"+detail.getContactwzmodel()+"','"+detail.getContactwzname()+"'," + ""+detail.getContactwznum()+",'"+detail.getContactwzunit()+"',"+detail.getContractMoney()+","+detail.getContractPrice()+")"; dao.getJdbcTemplate().update(sql); } } }

这个方法可以直接返回新添加的主表Id,类似于 jpa 的save(对象) 方法 也会直接commit 当然这个方法可以直接返回Id,另外我发现直接用JdbcTemplate 的实例对象update 也会提交事务,只是Id 需要我们再查一次而已

最后采用3方法,我估计JdbcTemplate 和 jpa 可能底层实现不一样吧 具体的实现原理和其中的原因还希望大家指出 另外如果有更好的方法也请指教 ~~~

转载请注明原文地址: https://www.6miu.com/read-2650241.html

最新回复(0)