PostgreSQL JDBC 子事务相关参数autosave和cleanupSavepoints

PostgreSQL JDBC 提供了 autosave 和 cleanupSavepoints 参数用于支持 PostgreSQL 子事务相关的操作。

1. autosave 参数

autosave 参数表示是否在执行 SQL 语句前自动增加 savepoint,可选值如下:

  • always,表示每个 SQL 在执行前会自动设置一个 savepoint
  • conservative,为每个 SQL 设置 savepoint,但是只有在缓存语句不能更改返回类型或者语句 XXX 无效等极少数情况下才会回滚
  • never,默认值,不会自动设置 savepoint

autosave 生效的前提是关闭自动提交,即参数 autocommit 设置为 false。

2. cleanupSavepoints 参数

cleanupSavepoints 参数表示 SQL 执行成功后,自动清除 savepoint,即自动执行一次 release savepoint 语句。默认值为 false,设置为 true 则会自动清除 savepoint。

3. autosave 和 cleanupSavepoints 示例

示例代码:

import java.sql.*;
import java.util.Properties;

public class Main{
    public static void main(String[] args)
    {
        String url = "jdbc:postgresql://127.0.0.1:36099/postgres?autosave=always&cleanupSavepoints=true";
        Properties props = new Properties();
        props.setProperty("user", "admin");
        props.setProperty("password", "123456");
        try {
                Connection conn = DriverManager.getConnection(url, props);
                conn.setAutoCommit(false);
                PreparedStatement st1 = conn.prepareStatement("insert into t(id) values(?)");
                st1.setInt(1, 1);
                int rowsInserted = st1.executeUpdate();
                System.out.println(rowsInserted + " rows inserted");
                st1.setInt(1, 2);
                rowsInserted = st1.executeUpdate();
                System.out.println(rowsInserted + " rows inserted");
                st1.close();
                conn.commit();
                conn.close();
        }catch (SQLException e) {
                e.printStackTrace();
        }
    }
}

执行示例代码:

[zhang@localhost java]$ java -Djava.ext.dirs=jdbc Main
1 rows inserted
1 rows inserted

打开数据库日志,log_statement = 'all',从数据库日志中可以看到执行的语句序列增加了 SAVEPOINT PGJDBC_AUTOSAVE 和 RELEASE SAVEPOINT PGJDBC_AUTOSAVE,如下:

BEGIN
SAVEPOINT PGJDBC_AUTOSAVE
insert into t(id) values($1),parameters: $1 = '1'
RELEASE SAVEPOINT PGJDBC_AUTOSAVE
SAVEPOINT PGJDBC_AUTOSAVE
insert into t(id) values($1),parameters: $1 = '2'
RELEASE SAVEPOINT PGJDBC_AUTOSAVE
COMMIT

设置了 autosave 之后,如果 SQL 执行发生异常,JDBC 会自动回滚当前子事务,内部会执行一次 ROLLBACK TO SAVEPOINT PGJDBC_AUTOSAVE 回滚当前报告报错的 SQL,业务在使用 autosave 时,应当捕捉执行异常,从业务端处理这些异常(忽略或者重试),这些异常不影响最顶层父事务的提交。

文章评论

0条评论