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条评论