嵌套事务 - 回滚方案

Sel*_*lva 9 java postgresql

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

    B{
    con.begin;
    .......
    .......
    con.commit;
    }
Run Code Online (Sandbox Code Playgroud)

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

Vin*_*lds 11

简短的回答,没有.答案如下.

在Java中支持嵌套事务取决于各种变量.

支持JTA中的嵌套事务

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

从Java Transaction API 1.1规范:

3.2.1开始交易

TransactionManager.begin方法启动全局事务,并将事务上下文与调用线程相关联.如果事务管理器实现不支持嵌套事务,则当调用线程已与事务关联时,TransactionManager.begin方法会发生NotSupportedException.

支持JDBC中的嵌套事务

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

自动提交的影响

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

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

您可能还想检查框架如何为嵌套事务提供支持,特别是如果您与JDBC API隔离或者自己启动新的JTA事务.


基于以上关于如何在各种场景中实现嵌套事务支持的描述,似乎代码中的回滚将回滚与Connection对象关联的所有更改.