[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[备忘]postgreSQL,事务中查询报错影响commit的问题

上一篇:[备忘]触发器小备忘
下一篇:[备忘]postgresql使用setFetchSize的注意事项

添加日期:2021/2/5 11:23:02 快速返回   返回列表 阅读848次
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类似的操作。
 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved