SpringService层调用Oracle存储过程保证同一事务在一个标记了@Transactional注解的SpringService层bean方法里调用了一个存储过程处理数据,后续还执行一系列的程序代码来处理数据,需要保证后面的程序代码报错后让存储过程插入更新的数据也回滚,即使用的数据库Connection为同一个,也就是说事务要是同一个。经多次测试发现,通过dataSource获取Connection或者SessionFactory的方式获取Connection,都不是同一个connection,因为连接池返回的不是同一个接连。但通过DataSourceUtil工具获取的连接为同一个connection,因为它是将连接通过TreadLocal的方式绑定在线程本地变量里,使得在整个线程的过程中都使用的是同一个数据库连接,而事务是基于同一个数据库连接的。例子:亲测可行!!!存储过程如下:createorreplaceprocedurePRC_TEST(jkdmxxinvarchar2,pclywidinnumber,flagoutnumber)isv_ErrorCodeNUMBER;v_ErrorTextVARCHAR2(2000);begininsertintoT_JFRXX(JFR_ID,JFR_MC,DLYHMC,JFZH,DW_ID,ZT,CJSJ)values(10000,'成功测试','成功测试123','033432-18015000601',10135,'100',sysdate);flag:=1;exceptionwhenothersthenflag:=0;v_ErrorCode:=SQLCODE;v_ErrorText:=SUBSTR(SQLERRM,1,200);rollback;insertintoT_JFRXX(JFR_ID,JFR_MC,DLYHMC,JFZH,DW_ID,ZT,CJSJ)values(10001,'失败测试','失败测试123','033432-18015000601',10135,'1',sysdate);commit;RAISE_APPLICATION_ERROR(-20001,'单机文件存储过程处理异常');--抛出异常让程序捕获endPRC_TEST;注意:存储过程正常业务逻辑代码里,不能有显示的commit;程序代码如下:@Override@Transactional(rollbackFor=Throwable.class,readOnly=false)publicvoidhandleFmData(ListLongpclwids)throwsSQLException{Connectionconnection=null;CallableStatementcstm=null;try{connection=DataSourceUtils.getConnection(dataSource);booleanisConnectionTransactional=DataSourceUtils.isConnectionTransactional(connection,dataSource);System.out.println(isConnectionTransactional);cstm=connection.prepareCall({callprc_test(?,?,?)});cstm=connection.prepareCall({callprc_test(?,?,?)});cstm.setString(1,Constant.JKXX_FMLXKPWJ_DSDJ);cstm.setInt(2,1);cstm.registerOutParameter(3,java.sql.Types.INTEGER);cstm.executeUpdate();IntegerretValue=cstm.getInt(3);System.out.println(存储过程返回值:+retValue);JfrxxjfrxxDB=jfrxxRep.findById(10000L);BizException.throwWhenNull(jfrxxDB,无法找到对象);//检查存储过程是否插入数据成功//后续的程序逻辑代码Jfrxxjfrxx=newJfrxx();jfrxx.setZt(1);jfrxx.setCjsj(TimeUtils.getSystemDateTime());jfrxx.setDlyhmc(后台代码);jfrxx.setDwId(10135L);jfrxx.setJfrMc(后台代码测试插入);jfrxx.setJfzh(033532-18015000601);jfrxxRep.save(jfrxx);}catch(Exceptione){logger.error(ExceptionUtils.getStackTrace(e));thrownewBizException(e);//只有这里抛出异常到事务方法外,才会回滚}finally{JdbcUtils.closeStatement(cstm);DataSourceUtils.releaseConnection(connection,dataSource);}}