zoukankan      html  css  js  c++  java
  • c# 和 sqlserver 中的事务

    c# 和 sqlserver 中的事务

    sqlserver 中的事务

          一提到事务,一般程序员对它的认识大概是这样的:原子性,以一个整体来执行,要么全部执行,要么全部返回(回滚),这是一个最初级的认识,更深入一点的请看我另外一篇文章:http://www.cnblogs.com/mc67/p/4823514.html

    今天我在这里做一下终结

    • 自动提交事务:是SQL Server默认的一种事务模式,每条Sql语句都被看成一个事务进行处理,你应该没有见过,一条Update 修改2个字段的语句,只修该了1个字段而另外一个字段没有修改。。
    • 显式事务:T-sql标明,由Begin Transaction开启事务开始,由Commit Transaction 提交事务、Rollback Transaction 回滚事务结束。
    • 隐式事务:使用Set IMPLICIT_TRANSACTIONS ON 将将隐式事务模式打开,不用Begin Transaction开启事务,当一个事务结束,这个模式会自动启用下一个事务,只用Commit Transaction 提交事务、Rollback Transaction 回滚事务即可。

    常用语句:

    • Begin Transaction:标记事务开始。
    • Commit Transaction:事务已经成功执行,数据已经处理妥当。
    • Rollback Transaction:数据处理过程中出错,回滚到没有处理之前的数据状态,或回滚到事务内部的保存点。
    • Save Transaction:事务内部设置的保存点,就是事务可以不全部回滚,只回滚到这里,保证事务内部不出错的前提下
    BEGIN TRAN
    SET XACT_ABORT ON
    INSERT INTO TEST VALUES(1999,12,80)
    INSERT INTO TEST VALUES(1999,12,80)
    SET XACT_ABORT OFF
    COMMIT TRAN
    GO

     或者你也可以这么写滴呀

    BEGIN TRANSACTION
         --你需要执行的更新,删除,插入的语句
    IF(@@ERROR > 0) //这是系统变量,存储你在执行更新,删除,插入操作时发生错误的记录编号
         ROLLBACK
    ELSE
       COMMIT 

    或者这........

    BEGIN TRAN
    INSERT INTO TEST VALUES(1998,12,23)
    IF(@@ERROR<>0)  --一旦报错,这个就不等于0 了滴呀;
      ROLLBACK TRAN
    ELSE
      BEGIN
      INSERT INTO TEST VALUES(1998,12,23)
      IF(@@ERROR<>0)
      ROLLBACK
      ELSE
      COMMIT TRAN
      END

    或者你可以这么写

    BEGIN TRY
       BEGIN TRAN
        INSERT TEST VALUES(1998,12,12)
        INSERT TEST VALUES(1998,12,'DF')
       COMMIT TRAN
    END TRY
    BEGIN CATCH
     ROLLBACK TRAN
      DECLARE @ERRMSG NVARCHAR(3000),
              @ERRLEVEL INT
               SELECT @ERRMSG=ERROR_MESSAGE(),
                      @ERRLEVEL=ERROR_SEVERITY()
                      RAISERROR(@ERRMSG,@ERRLEVEL,1)  
    END CATCH

     savepoint命令(在sql中为save tran或save transaction)
    保存点是事务过程中的一个逻辑点,我们可以把事务回退到这个点,而不必回退整个事务。

     在SQL Server中使用rollback会回滚所有的未提交事务状态,但是有些时候我们只需要回滚部分语句,把不需要回滚的语句提到事务外面来,虽然是个方法,但是却破坏了事务的ACID

    BEGIN TRAN
      INSERT INTO TEST VALUES(1995,15,15)
      SAVE TRAN POINT1
      INSERT INTO TEST VALUES(1995,15,15)
      ROLLBACK TRAN POINT1
      COMMIT TRAN

    结果只有一条数据插入进去滴呀;

    或者我们可以举一个更为 具体的是 列子;

    测试代码:

    CREATE TABLE ACCOUNT
    (
     ID INT PRIMARY KEY IDENTITY(1,1),
     NAME NVARCHAR(15),
     AMOUNT MONEY
    )
    GO
    INSERT INTO ACCOUNT 
    SELECT '刘奇',1300 UNION ALL
    SELECT '蔚蓝',400 

    事务代码:

    BEGIN TRAN TRAN_MONEY --开始事务
    
    DECLARE @TRAN_ERROR INT;
    SET @TRAN_ERROR=0;
    BEGIN TRY
        UPDATE ACCOUNT SET AMOUNT=AMOUNT-520 WHERE NAME='刘奇'
         SET @tran_error = @tran_error + @@ERROR;
        UPDATE ACCOUNT SET AMOUNT=AMOUNT+520 WHERE NAME='蔚蓝'
         SET @tran_error = @tran_error + @@ERROR;
    END TRY
    BEGIN CATCH
        PRINT '出现异常,异常编号:'+CONVERT(VARCHAR,ERROR_NUMBER())+
              '异常消息:'+ERROR_MESSAGE();
              SET @TRAN_ERROR+=1;
    END CATCH
    IF(@TRAN_ERROR>0)
    BEGIN
      --有异常 回滚事务;
      ROLLBACK TRAN;
      PRINT '转账失败,取消交易';
    END
    ELSE
    BEGIN
      --没有异常,提交事务
       COMMIT TRAN;
       PRINT '转账成功!'
    END

    ADO.NET中的事务

      public static void ExecuteSQLTran(string sqlString)
            {
                using (SqlConnection con = new SqlConnection(conString))
                {
                    using (SqlCommand cmd = new SqlCommand(sqlString, con))
                    {
                        con.Open();
                        SqlTransaction tran = con.BeginTransaction();
                        cmd.Transaction = tran; 
                        try
                        {
                            cmd.ExecuteNonQuery();
                            tran.Commit();
                        }
                        catch (Exception e)
                        {
                            tran.Rollback();
                        }
                        finally
                        {
                            con.Close();
                          
                        }
                    }
                }
            }

    c# net framework 中的事务

    TransactionScope是.Net Framework 2.0滞后,新增了一个名称空间。它的用途是为数据库访问提供了一个“轻量级”[区别于:SqlTransaction]的事务。使用之前必须添加对 System.Transactions.dll 的引用 

    在.net 1.1的时代,还没有TransactionScope类,因此很多关于事务的处理,都交给了SqlTransaction和SqlConnection,每个Transaction是基于每个Connection的。这种设计对于跨越多个程序集或者多个方法的事务行为来说,不是非常好,需要把事务和数据库连接作为参数传入。

    在.net 2.0后,TransactionScope类的出现,大大的简化了事务的设计。示例代码如下:

    static void Main(string[] args)
            {
                using (TransactionScope ts = new TransactionScope())
                {
                    userBLL u = new userBLL();
                    TeacherBLL t = new TeacherBLL();
                    u.ADD();
                    t.ADD();
                    ts.Complete();
                }
            }

    更多信息,请你参看:http://www.tuicool.com/articles/qaMzIb

    还需要开启.....

    TransactionScopeOptions

    描述

    Required

    如果已经存在一个事务,那么这个事务范围将加入已有的事务。否则,它将创建自己的事务。

    RequiresNew

    这个事务范围将创建自己的事务。

    Suppress

    如果处于当前活动事务范围内,那么这个事务范围既不会加入氛围事务 (ambient transaction),也不会创建自己的事务。当部分代码需要留在事务外部时,可以使用该选项。

    您可以在代码的任何位置上随是查看是否存在事务范围,具体方法就是查看 System.Transactions.Transaction.Current 属性。如果这个属性为“null”,说明不存在当前事务。

       public static void transactionscopeSQL(string sqlString)
            {
                //设置配置信息
                TransactionOptions options = new TransactionOptions();
                options.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted; //设置事务隔离级别;
                options.Timeout = new TimeSpan(0,0,60); //设置超时时间;
                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required,options))
                {
                    using (SqlConnection con = new SqlConnection(conString))
                    {
                        SqlCommand cmd = new SqlCommand(sqlString,con);
                        try
                        {
                            con.Open();
                            cmd.ExecuteNonQuery();
                            scope.Compelete();
                        }
                        catch (Exception e)
                        {
    
                        }
                        finally
                        {
                            scope.Dispose();
                        }
                    }
                   
                   
                }
            }

    更多事务信息:

    http://wangqingpei557.blog.51cto.com/1009349/748799/

  • 相关阅读:
    VUE 脚手架模板搭建
    defineProperty
    理解JS中的call、apply、bind方法
    Two-phase Termination模式
    打印样式设计
    浏览器内部工作原理
    Immutable Object模式
    怎么跳出MySQL的10个大坑
    控制台console
    整理的Java资源
  • 原文地址:https://www.cnblogs.com/mc67/p/5021374.html
Copyright © 2011-2022 走看看