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,则事务管理器最多可以支持嵌套事务.如果尝试在已与事务关联的线程中启动新事务,则任何开始事务的尝试都可能导致事务管理器(不支持嵌套事务)抛出NotSupportedException.
从Java Transaction API 1.1规范:
3.2.1开始交易
TransactionManager.begin方法启动全局事务,并将事务上下文与调用线程相关联.如果事务管理器实现不支持嵌套事务,则当调用线程已与事务关联时,TransactionManager.begin方法会发生NotSupportedException.
JDBC 3.0引入了Savepoint类,它或多或少类似于数据库中保存点的概念.必须使用返回Savepoint实例的Connection.setSavepoint()方法初始化保存点.可以使用Connection.rollback(Savepoint svpt)方法在稍后的时间点回滚到此保存点.当然,所有这些都取决于您是否使用支持JDBC 3.0的驱动程序,该驱动程序支持保存点的设置并回滚到它们.
默认情况下,获取的所有连接都设置为自动提交,除非JDBC驱动程序在此前面存在明显偏差.此功能(如果启用)会自动排除嵌套事务的范围,因为通过连接在数据库中进行的所有更改都会在执行时自动提交.
如果禁用自动提交功能,并选择显式提交和回滚事务,则提交事务始终会提交连接执行的所有更改,直到该时间点为止.请注意,为提交选择的更改不能由程序员定义 - 直到该时刻的所有更改都被选择用于提交,无论它们是在一种方法还是另一种方法中执行.唯一的出路是定义保存点,或者破解你的方式通过JDBC驱动程序 - 驱动程序通常会提交由与线程关联的连接执行的所有更改,因此启动新线程(这很糟糕)并在其中获取新连接,经常给你一个新的交易背景.
您可能还想检查框架如何为嵌套事务提供支持,特别是如果您与JDBC API隔离或者自己启动新的JTA事务.
基于以上关于如何在各种场景中实现嵌套事务支持的描述,似乎代码中的回滚将回滚与Connection对象关联的所有更改.