zoukankan      html  css  js  c++  java
  • Transaction And Lock--存在嵌套事务吗?

    在很多编程语言中,可以实现嵌套,但在TSQL中,可以实现嵌套事务吗?

    答案:不可以

    虽然我们可以写如下code:

    CREATE TABLE #TB1

    (

    ID INT

    )

    --创建事务1

    BEGIN TRAN TR1

    INSERT INTO #TB1

    SELECT 1

    --在事务1中创建事务2

    BEGIN TRAN TR2

    INSERT INTO #TB1

    SELECT 2

    --回滚事务

    ROLLBACK TRAN

    SELECT * FROM #TB1

    DROP TABLE #TB1

    以上代码能够正常运行,且事务1和事务2都被回滚,看似实现了嵌套事务,但是我们在事务1中,不能指定回滚事务2,以下代码会出错:

    CREATE TABLE #TB1

    (

    ID INT

    )

    --创建事务1

    BEGIN TRAN TR1

    INSERT INTO #TB1

    SELECT 1

    --在事务1中创建事务2

    BEGIN TRAN TR2

    INSERT INTO #TB1

    SELECT 2

    --尝试回滚事务2

    ROLLBACK TRAN TR2

    --在尝试提交事务1

    COMMIT TRAN TR1

    SELECT * FROM #TB1

    DROP TABLE #TB1

    以上错误是对事务的一种错误认识,以其他编程的思想去编写TSQL,我们知道事务可以提交和回滚,所以我们尝试用嵌套事务来实现部分回滚,其实我们只需要一个事务,并在最终决定提交事务还是回滚事务,在事务中,如果需要部分回滚,我们只需使用事务保存点便可以实现:

    CREATE TABLE #TB1

    (

    ID INT

    )

    --创建事务1

    BEGIN TRAN TR1

    INSERT INTO #TB1

    SELECT 1

    --创建事务保存点1

    SAVE TRAN savepoint1

    INSERT INTO #TB1

    SELECT 2

    --将事务回滚到事务检查点1之前

    ROLLBACK TRAN savepoint1

    COMMIT TRAN TR1

    SELECT * FROM #TB1

    DROP TABLE #TB1

    结论:

    1.可以在一个事务中创建一个新的事务,但无法使之嵌套,即内层事务相对于外层事务而言独立存在,任何回滚都将回滚所有事务,且这些“嵌套”事务间无隔离性。

    2.要想在事务里进行部分回滚,可以使用事务保存点来实现。

  • 相关阅读:
    数据库索引概念与优化
    数据库查询效率分析
    C语言结构体与C++结构体之间的差异
    判断一个序列是否为栈的弹出序列
    C语言中的结构体
    C++ STL 中的 std::sort()
    Spring注入值到静态变量
    层次遍历二叉树
    计算二叉树的大小
    计算二叉树的高度
  • 原文地址:https://www.cnblogs.com/TeyGao/p/3522971.html
Copyright © 2011-2022 走看看