• MSSQLSERVER数据库 使用C#来操作事务


     就在不久前,我在博客园看到一个名为英雄默问出处的博客。他里面有两篇是介绍用C#来操作事务的。用C#来操作事务和用SQL语句来操作事务原理是一模一样的。总结起来有三个步骤:

    1.开启事务

    2.判断执行的SQL语句有没有出错,如果没有就将执行完SQL语句后提交事务

    3.如果有错,那么就回滚事务

     

      在操作事务上还分为本地事务和分布式事务。我从网上百度下来他们的定义,如下:
      本地事务:将多项任务绑定在一起,使其作为单个工作单元来执行
      分布式事务:分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。

      上面的定义没看懂也没关系,其实我看这些定义也挺烦的。记得有一回考操作系统,当时老师在课堂上说了一句可能会考定义,例如操作系统是什么,结果呢?操作系统是什么这句我背了好几遍。临到考前的早上还起来再读一次。考后就忘记了。这样的考试也够折腾人的了。
      
    我们可以通俗的理解成,本地事务就是操作单个数据库的。而分布式事务就是操作多个数据库的。

       

      下面用三个小例子来说明一下C#怎么操作事务。

    •   第一个小例子结合存储过程和事务来操作。
    •   第二个小例子使用ADO.NET里面的一个类SqlTransaction来操作本地事务。
    •   第三个小例子使用TransactionScope类操作,使用TransactionScope时需添加引用命名空间,再using System.Transactions

     

    在看这三个小例子前先看一下数据库用的表,为了测试,一切都非常简单

    test数据库的bank表有哪些字段的数据

    bid balance
    001  400.00
    002  2100.00

    testLog数据库里的bankLo有哪些字段的数据

    id bid oldBalance newBalance logtime
    1 002  2100.00 1100.00 2010-09-01 00:00:00.000
    2 002  2100.00 1100.00 2010-09-01 00:00:00.000

     

    第一小例子

    先在数据库里他建存储过程,里面写上事务的SQL语句

    View Code
    USE [test]
    GO
    /****** Object:  StoredProcedure [dbo].[proc_bankTransaction]    Script Date: 08/19/2012 10:42:05 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER procedure [dbo].[proc_bankTransaction]
    (
        @result int output --0表示提交事务失败,表示提交事务成功
    )
    AS
    BEGIN
        declare @sumError int
        set @sumError=0
        BEGIN TRANSACTION  --开启事务
        update bank set balance=balance-100 where bid='001';
        set @sumError = @sumError +@@Error
        update bank set balance=balance+1000 where bid='002';
        set @sumError = @sumError +@@Error
         
            IF(@sumError = 0)
                BEGIN
                    set @result=1 --提交事务,表示提交事物成功
                    COMMIT TRANSACTION
                END
            ELSE
                BEGIN
                    set @result=0 --回滚事务,表示回滚事务
                    ROLLBACK TRANSACTION
                END
    END

    C#操作的语句代码:

     

            static void Main(string[] args)
            {
    
                using (SqlConnection conn = new SqlConnection("server=.;database=test;uid=sa;pwd=123456"))
                {
                    conn.Open();
                    using (SqlCommand cmd = new SqlCommand("proc_bankTransaction", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        SqlParameter[] paras ={
                            new SqlParameter("@result",SqlDbType.Int)
                        };
                        paras[0].Direction = ParameterDirection.Output;
                        try
                        {
                            cmd.Parameters.AddRange(paras);
                            cmd.ExecuteNonQuery();
                            Console.Write(paras[0].Value);//输出1表示成功,输出0表示失败
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    }
    
                }
                Console.ReadLine();
    
            }

     

    第二个小例子:使用ADO.NET里面的一个类SqlTransaction来操作本地事务

    View Code
     1 namespace ConsoleApplication1
     2 {
     3     class Program
     4     {
     5         static void Main(string[] args)
     6         {
     7 
     8             using (SqlConnection conn = new SqlConnection("server=.;database=test;uid=sa;pwd=123456"))
     9             {
    10                 conn.Open();
    11                 using (SqlCommand cmd = conn.CreateCommand())
    12                 {
    13                     SqlTransaction transaction = conn.BeginTransaction();//开始事物
    14                     cmd.Transaction = transaction;
    15                     try
    16                     {
    17                         cmd.Connection = conn;
    18                         cmd.CommandText = "update bank set balance='500' where bid='001'";
    19                         cmd.ExecuteNonQuery();
    20 
    21                         cmd.CommandText = "update bank set balance='2100' where bid='002'";
    22                         cmd.ExecuteNonQuery();
    23 
    24                         transaction.Commit();//如果都成功那么提交事物
    25                     }
    26                     catch (Exception ex)
    27                     {
    28                         Console.Write(ex.Message);
    29                         transaction.Rollback();//出现错误,进行回滚
    30                     }
    31                 }
    32             }
    33 
    34             Console.ReadLine();
    35 
    36 
    37         }
    38     }
    39 }


    第三个小例子:使用TransactionScope类操作,使用TransactionScope时需添加引用命名空间,再using System.Transactions

    View Code
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Data;
     6 using System.Data.SqlClient;
     7 using System.Transactions;
     8 namespace ConsoleApplication1
     9 {
    10     class Program
    11     {
    12         static void Main(string[] args)
    13         {
    14 
    15             string bankStr = "server=.;database=test;uid=sa;pwd=123456";
    16             string bankLogStr = "server=.;database=testLog;uid=sa;pwd=123456";
    17 
    18             //为了简化操作步骤,假设我们已经知道是原来的balance的值为2100,更改后的值为1100
    19             using (TransactionScope scope = new TransactionScope())
    20             {
    21                 try
    22                 {
    23                     using (SqlConnection conn = new SqlConnection(bankStr))
    24                     {
    25                         conn.Open();
    26                         using (SqlCommand cmd = conn.CreateCommand())
    27                         {
    28                             cmd.CommandText = "update bank set balance='1100' where bid='002'";
    29                             cmd.ExecuteNonQuery();
    30                         }
    31                     }
    32 
    33                     using (SqlConnection connBankLog = new SqlConnection(bankLogStr))
    34                     {
    35                         connBankLog.Open();
    36                         using (SqlCommand cmd = connBankLog.CreateCommand())
    37                         {
    38                             cmd.CommandText = "insert into bankLog(bid,oldBalance,newBalance,logtime) values('002','2100','1100','2010-09-01');";
    39 
    40                             cmd.ExecuteNonQuery();
    41                         }
    42                     }
    43                     scope.Complete();
    44                 }
    45                 catch (Exception ex)
    46                 {
    47                     Console.Write(ex.Message);
    48                 }
    49             }
    50             Console.ReadLine();
    51 
    52         }
    53     }
    54 }

     

     

     

  • 相关阅读:
    ACM: SCU 4440 Rectangle
    ACM: NBUT 1646 Internet of Lights and Switches
    ACM: Long Live the Queen
    ACM: Racing Gems
    C++ 11 笔记 (一) : lambda
    cocos2d-x笔记2: 编译到安卓的步骤与注意事项
    C++笔记1: 单例模式。(一个简单的设计模式在C++中复杂出翔。。)
    Java笔记2 : 泛型的体现,及其上限、下限、通配符
    我终于忍不住喷一下某些书了,关于Java传引用的XX言论
    Java笔记1 : 在生产者消费者模式中,线程通信与共享数据,死锁问题与解决办法
  • 原文地址:https://www.cnblogs.com/cxeye/p/2646241.html
Copyright © 2020-2023  润新知