zoukankan      html  css  js  c++  java
  • 【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,且第一个存储过程执行没有问题。
    -- 但是因为第二个存储过程因为主键冲突执行失败,所以最外层事务会进行回滚,因此测试表中没有插入任何数据。

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

  • 相关阅读:
    CentOS最常用命令
    cssreset
    mysql cmd连接 乱码
    帮朋友转发招聘信息 南京知名互联网公司招聘java、测试、前端,具体私聊
    InputStream写文件出现大量NUL
    iOS app开发资料整理
    完美的视图旋转算法
    Windows上使用clang编译
    nodejs
    Rpath handling on Linux
  • 原文地址:https://www.cnblogs.com/WillYang/p/3238541.html
Copyright © 2011-2022 走看看