• 【SQL】关于存储过程调用过程中事务的点点滴滴


    1、调用两个存储过程

    ----------------------------------------------------------------
    -- 表[dbo].[aaa_test]中[id]为主键
    ----------------------------------------------------------------
    
    -- 存储过程1
    ALTER PROCEDURE [dbo].[aaa_test_proc1]
        @p_id    int,
        @p_name    varchar(50)
    AS
    BEGIN
        INSERT INTO [dbo].[aaa_test]
                   ([id]
                   ,[name])
             VALUES
                   (@p_id
                   ,@p_name)
    END
    
    ----------------------------------------------------------------
    
    -- 存储过程2
    ALTER PROCEDURE [dbo].[aaa_test_proc2]
        @p_id    int,
        @p_name    varchar(50)
    AS
    BEGIN
        INSERT INTO [dbo].[aaa_test]
                   ([id]
                   ,[name])
             VALUES
                   (@p_id
                   ,@p_name)
    END
    
    ----------------------------------------------------------------
    
    -- 调用两个存储过程
    exec dbo.aaa_test_proc1 '1','事务测试1'
    exec dbo.aaa_test_proc2 '1','事务测试2'
    
    ----------------------------------------------------------------
    
    -- 结果
    --(1 行受影响)
    --消息 2627,级别 14,状态 1,过程 aaa_test_proc2,第 11 行
    --违反了 PRIMARY KEY 约束 'PK_aaa_test'。不能在对象 'dbo.aaa_test' 中插入重复键。
    --语句已终止。
    
    -- 表[dbo].[aaa_test]:
    id
    name
    1
    事务测试1






    -- 【结论】:不明确指定事务时,两次存储过程调用是分开的两个事务

    2、在同一个事务中调用两个存储过程,没有事务的嵌套

    ----------------------------------------------------------------
    -- 表[dbo].[aaa_test]中[id]为主键
    ----------------------------------------------------------------
    
    -- 存储过程1
    ALTER PROCEDURE [dbo].[aaa_test_proc1]
        @p_id    int,
        @p_name    varchar(50)
    AS
    BEGIN
        INSERT INTO [dbo].[aaa_test]
                   ([id]
                   ,[name])
             VALUES
                   (@p_id
                   ,@p_name)
    END
    
    ----------------------------------------------------------------
    
    -- 存储过程2
    ALTER PROCEDURE [dbo].[aaa_test_proc2]
        @p_id    int,
        @p_name    varchar(50)
    AS
    BEGIN
        INSERT INTO [dbo].[aaa_test]
                   ([id]
                   ,[name])
             VALUES
                   (@p_id
                   ,@p_name)
    END
    
    ----------------------------------------------------------------
    
    -- 调用两个存储过程
    BEGIN TRY 
        BEGIN TRAN 
            exec dbo.aaa_test_proc1 '1','事务测试1'
            exec dbo.aaa_test_proc2 '1','事务测试2'
        COMMIT TRAN 
    END TRY 
    BEGIN CATCH 
        ROLLBACK TRAN 
    END CATCH
    
    ----------------------------------------------------------------
    
    -- 结果
    --(1 行受影响)
    
    -- 表[dbo].[aaa_test]:
    id
    name
    -- 【结论】:在同一个事务中调用多个存储过程,其中一个出错后,全部回滚。

    3、事务嵌套

    ----------------------------------------------------------------
    -- 表[dbo].[aaa_test]中[id]为主键
    ----------------------------------------------------------------
    
    -- 存储过程1
    ALTER PROCEDURE [dbo].[aaa_test_proc1]
        @p_id    int,
        @p_name    varchar(50)
    AS
    BEGIN
        BEGIN TRY 
            BEGIN TRAN 
                INSERT INTO [dbo].[aaa_test]
                           ([id]
                           ,[name])
                     VALUES
                           (@p_id
                           ,@p_name)
                COMMIT TRAN 
        END TRY 
        BEGIN CATCH 
            ROLLBACK TRAN 
        END CATCH
    END
    
    ----------------------------------------------------------------
    
    -- 存储过程2
    ALTER PROCEDURE [dbo].[aaa_test_proc2]
        @p_id    int,
        @p_name    varchar(50)
    AS
    BEGIN
        INSERT INTO [dbo].[aaa_test]
                   ([id]
                   ,[name])
             VALUES
                   (@p_id
                   ,@p_name)
    END
    
    ----------------------------------------------------------------
    
    -- 调用两个存储过程
    BEGIN TRY 
        BEGIN TRAN 
            exec dbo.aaa_test_proc1 '1','事务测试1'
            exec dbo.aaa_test_proc2 '1','事务测试2'
        COMMIT TRAN 
    END TRY 
    BEGIN CATCH 
        ROLLBACK TRAN 
    END CATCH
    
    ----------------------------------------------------------------
    
    -- 结果
    --(1 行受影响)
    
    -- 表[dbo].[aaa_test]:
    
    id
    name
    -- 【结论】:事务嵌套时,以最外层事务的执行情况为准。
    -- 例子中,虽然在第一个存储过程的子事务中有commit tran,且第一个存储过程执行没有问题。
    -- 但是因为第二个存储过程因为主键冲突执行失败,所以最外层事务会进行回滚,因此测试表中没有插入任何数据。

    -----打完收工-----

  • 相关阅读:
    仿佛看到了曾经在电子厂的自己
    TP5 condition 多个条件如何写
    电子数据时代我该如何保存我的数据?
    Shell脚本查询磁盘数量
    缺少维生素?
    html5的页面在IOS中,按钮 变成圆角怎么办?
    生物信息数据分析准则
    用variant的数据来推导基因表达 | Imputation of Expression Using PrediXcan
    Rare-Variant Association Analysis | 罕见变异的关联分析
    英语语法
  • 原文地址:https://www.cnblogs.com/WillYang/p/3238541.html
Copyright © 2020-2023  润新知