• SQL 事务


    首先声明,以下是个人见解,如有错误望指出,先谢谢!

          我们知道数据库(SQL) 的事务,现在我讲讲我的大概了解:

         数据库的事务使用基本语法: 

    begin try
    	begin tran [tranName]
    	 --语句
    	commit tran [tranName]
    end try
    begin catch
       rollback tran [tranName]
    end catch
    

    [] 表示可有可无,

    try catch 我就不说了。 数据库执行事务成功与否 看的是计数,即 begin tran  和 commit tran 的计数。当计数一样就成功,不成功报如下错误:

    EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 1,当前计数 = 2 , 只要是两个计数不一样,就会出现错误

    一般写事务就是一层,所以 有没有事务名一样,当事务有多层(存储过程调用存储过程,循环调用存储过程(存储过程都是带事务的)) 这时候事务名是很重要的

    简单说一下,当有A(含事务) 存储过程调用B(含事务)存储过程,如果 B 事务不指定事务名,当B 回滚的时候会将 A 的存储过程 计数也回滚,导致两个计数不一致,

    如果 B 事务指定事务名,将不会影响 A 事务的计数。这就是有事务名和没有事务名的区别,一句话:有事务名就是当前事务,没有事务名就是整个事务。

    C# 中有个 SqlTransaction 类,怎么使用我就不说了,这个类的事务和数据库的事务是一样的,他们公用同一个进程,也就是说 在C# 类里有事务,在执行的SQL里

    也有事务,当把SQL里的事务提交(没有指明事务名的情况) 会导致 C# 当前的 事务对象为null.

    这里顺便说下: set xact_abort on   这个设置是指 出错后自动回滚,一般用在存储过程中。

    下面给一个事务嵌套的例子:

    表结构:

    CREATE TABLE [dbo].[Test](
    	[Id] [int] IDENTITY(1,1) NOT NULL,
    	[Name] [nvarchar](5) NOT NULL
    ) ON [PRIMARY]
    

    子事务:

    CREATE procedure [dbo].[CreateSubTran]
    (
      @Name nvarchar(50), 
      @Status int output
    )
    as 
    begin
        begin try
           print '准备开始:'+CAST(@@TRANCOUNT AS VARCHAR(50))
          begin tran currentTran
           save tran preTran
             print '事务开始:'+CAST(@@TRANCOUNT AS VARCHAR(50))
          insert test(Name)
          values(@Name)
          set @Status=1 
           print '执行成功:'+CAST(@@TRANCOUNT AS VARCHAR(50))    
          commit tran currentTran
          print 'commit'
        end try
        begin catch
         print '出错回滚前:'+CAST(@@TRANCOUNT AS VARCHAR(50))
            if(@@TRANCOUNT>0)
            begin
    			rollback tran preTran
            end
            set @Status=-1    
            commit tran currentTran
            print '出错回滚后:'+CAST(@@TRANCOUNT AS VARCHAR(50))
            return 0
        end catch   
    
    end
    

     父事务:

    create proc CreateParentTran
    as
    begin
    declare @result int
        begin try
        begin tran 
         exec  [CreateSubTran] 'sdfsd',@result output
         commit tran
        end try
        begin catch
           rollback tran
        end catch 
    end
    

     注意: 最外层事务可以不用指定事务名,嵌套事务必须指定事务名,上面已经讲的很清楚。

    如图结果:事务开始的计数必须与结束的计数是一样的

    当事务执行回滚后,当前的计数 就等于事务还未开始前的计数。

     

  • 相关阅读:
    Codeforces 17.E Palisection
    poj4052 Hrinity
    bzoj2565 最长双回文串
    Java基础知识强化之集合框架笔记43:Set集合之TreeSet存储Integer类型的元素并遍历
    Java基础知识强化之集合框架笔记42:Set集合之LinkedHashSet的概述和使用
    Java基础知识强化之集合框架笔记41:Set集合之HashSet存储自定义对象并遍历练习
    Java基础知识强化之集合框架笔记40:Set集合之HashSet存储自定义对象并遍历
    TCP/IP协议原理与应用笔记13:底层网络技术之传输介质
    Java基础知识强化之集合框架笔记39:Set集合之HashSet存储字符串并遍历
    Java基础知识强化之集合框架笔记38:Set集合之Set集合概述和特点
  • 原文地址:https://www.cnblogs.com/startlearn/p/4675083.html
Copyright © 2020-2023  润新知