postgreSQL,在事务中间执行了查询语句。 try{ 执行selelct语句 } catch (Exception e) { .. } 这个查询报错,虽然catch了,但是后面commit会出错。 current transaction is aborted, commands ignored until end of transaction block -------------------------- (1)使用savepoint,类似这样: Connection conn = null; Savepoint savepoint = null; try { conn = getConnection(); savepoint = conn.setSavepoint(); //execute some query } catch(SQLException e) { if(conn != null && savepoint != null) { conn.rollback(savepoint); } } finally { if(conn != null) { try { conn.close(); } catch(SQLException e) {}
} } 这样可以,但是有个问题,如果外面调用时没开事务,这里就会报错了 org.postgresql.util.PSQLException: 在自动确认事物交易模式无法建立储存点(Savepoint)。 ------------------------------------------------ (2)新开一个事务 开始抄了一段,这么写的:
Connection conn = null; PlatformTransactionManager tm = null; TransactionStatus ts = null; try { tm = ClientDataSourceService.getTransactionManager(); ts = tm.getTransaction(new DefaultTransactionDefinition()); conn = DataSourceUtils.getConnection(dataSource); try{ 执行selelct语句 } catch (Exception e) { .. }
} finally { tm.rollback(ts); // rollback //释放连接 DataSourceUtils.releaseConnection(conn, dataSource); } 显示日志如下: Participating in existing transaction Participating transaction failed - marking existing transaction as rollback-only Setting JDBC transaction [org.postgresql.jdbc.PgConnection@1ffc189f] rollback-only java.sql.SQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block Query 里面rollback了,外面不能用了,变成rollback-only了,后面执行insert时直接抛出异常 问题在这句话:Participating in existing transaction 参与存在的事务,也就是没有新开事务 ------------------------------------- 改成:new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_NOT_SUPPORTED)) 就行了 也就是里面不支持事务。
外面没开事务的话,是这样: Fetching JDBC Connection from DataSource Should roll back transaction but cannot - no transaction available 不会出错。
外面开了事务的话,是这样: Suspending current transaction Fetching JDBC Connection from DataSource Should roll back transaction but cannot - no transaction available Resuming suspended transaction after completion of inner transaction 先挂起外面的事务,然后执行里面,然后恢复外面的事务。 ------------------ 事务级别: 1.DEFAULT默认级别:DEFAULT为数据源(数据库)的默认隔离级别,默认的隔离级别通常为PROPAGATION_REQUIRED。 2.PROPAGATION_SUPPORTS: 支当前事务,如果当前没有事务,就以非事务方式执行。 3.PROPAGATION_REQUIRED:支持当前事务,如果当前有事务, 那么加入事务, 如果当前没有事务则新建一个(默认情况) 4.PROPAGATION_MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常。 5.PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。6.PROPAGATION_NOT_SUPPORTED :以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 7.PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。 8.PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
|