java - 嵌套事务——回滚场景

标签 java postgresql

A(){
    con.begin;
    .........
    .........
    B();
    ........
    ........(con.rollback;)
    con.commit;
    }

    B{
    con.begin;
    .......
    .......
    con.commit;
    }

在上面的代码中,我在 A() 处开始了一个新的数据库事务。它成功执行了一些事务。之后 B() 开始执行,它也成功执行了一些事务,现在控制权返回到 A()。此时发生了一些异常,我进行了回滚。我想知道在 B() 中成功的事务是否会回滚。

最佳答案

简短的回答,不。长答案如下。

Java 中对嵌套事务的支持取决于起作用的各种变量。

支持 JTA 中的嵌套事务

首先,如果您使用的是 JTA,则由事务管理器来支持嵌套事务。如果尝试在已与事务关联的线程中启动新事务,则任何启动事务的尝试都可能导致事务管理器(不支持嵌套事务)抛出 NotSupportedException。

来自 Java Transaction API 1.1 规范:

3.2.1 Starting a Transaction

The TransactionManager.begin method starts a global transaction and associates the transaction context with the calling thread. If the Transaction Manager implementation does not support nested transactions, the TransactionManager.begin methodthrowsthe NotSupportedException whenthe calling thread is already associated with a transaction.

支持 JDBC 中的嵌套事务

JDBC 3.0 引入了 Savepoint类,它或多或少类似于数据库中保存点的概念。必须使用 Connection.setSavepoint() 初始化保存点返回保存点实例的方法。可以在稍后使用 Connection.rollback(Savepoint svpt) 回滚到此保存点。方法。当然,所有这些都取决于您是否使用了支持保存点设置和回滚的 JDBC 3.0 兼容驱动程序。

自动提交的影响

默认情况下,所有获得的连接都设置为自动提交,除非 JDBC 驱动程序在这方面有明显的偏差。如果启用此功能,则会自动排除嵌套事务的范围,因为通过连接在数据库中所做的所有更改都会在执行时自动提交。

如果您禁用自动提交功能,并选择显式提交和回滚事务,那么提交事务总是会提交连接执行的所有更改,直到该时间点为止。请注意,为提交选择的更改不能由程序员定义 - 在该时刻之前的所有更改都被选择为提交,无论它们是在一种方法还是另一种方法中执行的。唯一的出路是定义保存点,或者破解 JDBC 驱动程序 - 驱动程序通常会提交与线程关联的连接执行的所有更改,因此启动一个新线程(这很糟糕)并在其中获取一个新连接, 通常会为您提供新的事务上下文。

您可能还想检查您的框架如何为嵌套事务提供支持,尤其是当您与 JDBC API 隔离或无法自行启动新的 JTA 事务时。


根据上面关于如何在各种情况下实现嵌套事务支持的描述,您的代码中的回滚似乎将回滚与 Connection 对象关联的所有更改。

关于java - 嵌套事务——回滚场景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3786568/

相关文章:

java - 谓词过滤器 rxjava2 - 如何传递动态过滤器参数

java - 如何启用Spring安全性?

java - 检查整数是否在 jsonb 列表中

postgresql - 这两种函数有什么区别?

sql - 将sql ddl文件上传到postgresql数据库

ruby-on-rails - 处理 heroku 上不存在的表的 drop_table 迁移

java - 从列表中删除类型的项目

java - response.sendRedirect() 和 request.getRequestDispatcher().forward(request,response) 有什么区别

java - 减去不同的 double 结果为 0.0

postgresql - 如何通过终端在psql中保存查询