嵌套事务 - 回滚方案 [英] Nested transactions - Rollback scenario

查看:309
本文介绍了嵌套事务 - 回滚方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

In the above code, I begin a new DB transaction at A(). It executes some transaction successfully. After that B() starts executing and it also executes some transaction successfully and now the control returns to A(). At this point some exception occurs and I do a rollback. I would like to know whether the transaction which succeeded in B() will rollback or not.

推荐答案

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

The short answer, no. The long answer is as follows.

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

Support for nested transactions in Java depends on various variables at play.

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

First and foremost, if you are using JTA, it is upto to the Transaction Manager to support nested transactions. Any attempt to begin a transaction may result in a NotSupportedException being thrown by a Transaction Manager (that does not support nested transactions) if there is an attempt to start a new transaction in a thread that is already associated with a transaction.

来自Java Transaction API 1.1规范:

From the Java Transaction API 1.1 specification:


3.2.1开始交易

TransactionManager.begin方法启动
a全局事务,并将
事务上下文与
调用线程关联。如果Transaction
Manager实现没有
支持嵌套事务,那么
TransactionManager.begin
方法在调用线程已经是
与事务关联时,返回NotSupportedException

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引入了< a href =http://download.oracle.com/javase/6/docs/api/java/sql/Savepoint.html\"rel =noreferrer> Savepoint 类,或多或少类似于数据库中保存点的概念。必须使用初始化保存点Connection.setSavepoint()方法,返回Savepoint的实例。可以使用 Connection.rollback(Savepoint svpt)方法。当然,所有这些都取决于您是否使用支持JDBC 3.0的驱动程序来支持设置保存点并回滚它们。

Support for Nested transactions in JDBC

JDBC 3.0 introduces the Savepoint class, which is more or less similar to the concept of savepoints in the database. Savepoints have to be initialized using the Connection.setSavepoint() method that returns an instance of a Savepoint. One can roll back to this savepoint at a later point in time using the Connection.rollback(Savepoint svpt) method. All of this, of course, depends on whether you are using a JDBC 3.0 compliant driver that supports setting of savepoints and rolling back to them.

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

By default, all connections obtained are set to auto-commit, unless there is a clear deviation on this front by the JDBC driver. This feature, if enabled, automatically rules out the scope of having nested transactions, for all changes made in the database via the connection are committed automatically on execution.

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

If you disable the auto-commit feature, and choose to explicitly commit and rollback transactions, then committing a transaction always commits all changes performed by a connection until that point in time. Note, that the changes chosen for commit cannot be defined by a programmer - all changes until that instant are chosen for commit, whether they have been performed in one method or another. The only way out is to define savepoints, or hack your way past the JDBC driver - the driver usually commits all changes performed by a connection associated with a thread, so starting a new thread (this is bad) and obtaining a new connection in it, often gives you a new transaction context.

您可能还想检查框架如何为嵌套事务提供支持,特别是如果您与JDBC API隔离或从你自己开始新的JTA交易。

You might also want to check how your framework offers support for nested transactions, especially if you're isolated from the JDBC API or from starting new JTA transactions on your own.

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

Based on the above description of how nested transaction support is possibly achieved in various scenarios, it appears that a rollback in your code will rollback all changes associated with the Connection object.

这篇关于嵌套事务 - 回滚方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆