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 }

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM