国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

c#中SqlTransaction——事務詳解

2019-10-29 21:18:36
字體:
來源:轉載
供稿:網友

事務處理基本原理     

事務是將一系列操作作為一個單元執行,要么成功,要么失敗,回滾到最初狀態。在事務處理術語中,事務要么提交,要么中止。若要提交事務,所有參與者都必須保證對數據的任何更改是永久的。不論系統崩潰或是發生其他無法預料的事件,更改都須是持久的。只要有一個參與者無法做出此保證,整個事務就會失敗。事務范圍內的所有數據更改將回滾到特定設置點。  

sql,事務,transaction,用法,c#,sqltransaction

事務將多個操作緊密聯系到一起,這樣就能保證有聯系的兩種操作的一致性、以及數據的完整性。舉個簡單例子:公司的員工信息管理系統,現在要錄入數據,員工信息系統假設只有部門、員工信息兩張表,其中員工信息表中有標識部門的字段。在你錄入信息的時候首先你得錄入部門信息,再錄入員工信息。具體實現代碼: 

private static void ExecuteSqlTransaction(string connectionString)    {      using (SqlConnection connection = new SqlConnection(connectionString))      {        connection.Open();        SqlCommand command = connection.CreateCommand();        SqlTransaction transaction;         transaction = connection.BeginTransaction("SampleTransaction");        command.Connection = connection;        command.Transaction = transaction;        try        {          command.CommandText =            "Insert into Department (ID, Name) VALUES (1, '工程部')";          command.ExecuteNonQuery();          command.CommandText =            "Insert into Users(ID, Name,DepartmentID) VALUES (1, 'xyz',1)";          command.ExecuteNonQuery();          transaction.Commit();        }        catch (Exception ex)        {          transaction.Rollback();        }      }    }

 事務的誤區

事務有很多優點【原理中已經闡述】,由于它的要求比較高,所以注意事務不能濫用,如果用不好就會造成很大的麻煩。

事務有一個開頭和一個結尾,它們指定了事務的邊界,事務在其邊界之內可以跨越進程和計算機。事務邊界內的所有資源都參與同一個事務。要維護事務邊界內資源間的一致性,事務必須具備 ACID 屬性,即原子性、一致性、隔離性和持續性。這是MSDN的權威說明。

也許針對一般的小邏輯、小數據事務應用非常的高效、可靠。但如果數據量很大,在單個事務中集合的操作繁多而且復雜,事務的致命傷就會暴露出來。一個事務進行時,必須保證邊界資源的原子性、一致性、隔離性和持續性。

 我曾經設計了一個測試用例,測試事務在執行時對資源的利用情況。測試結果很令人驚訝:在事務執行時,獨占事務涉及到的數據表,造成其它操作詞表的功能,因等待時間過長,而暴跳“獲得數據連接超時”的警告。

 具體的測試用例:      
Transaction

public class TestTransaction  {    /// <summary>    /// 插入新用戶    /// </summary>    /// <param name="tran"></param>    /// <returns></returns>    private static bool InsertIntoUser(SqlTransaction tran)    {      string strSql = @"INSERT INTO [T_User]                      ([F_Name])                   VALUES                      (@F_Name)";      SqlParameter[] Params ={ new SqlParameter("@F_Name", SqlDbType.VarChar, 20) };      Params[0].Value="Test1001";      int count= SqlHelper.ExecuteNonQuery(strSql,Params,tran);      if (count > 0)      {        return true;      }      else      {        return false;      }    }    /// <summary>    /// 插入title    /// </summary>    /// <returns></returns>    private static bool InsertIntoTitle(SqlTransaction tran)    {      string strSql = @"INSERT INTO [T_User_Title]                    ([F_TitleName],                    [F_Remark],                    [F_Status],                    [F_EditTime])                 VALUES                    (@F_TitleName,                    @F_Remark,                    @F_Status,                    @F_EditTime)";      SqlParameter[] Params = {         new SqlParameter("@F_TitleName",SqlDbType.VarChar, 50),         new SqlParameter("@F_Remark", SqlDbType.VarChar, 200),         new SqlParameter("@F_Status", SqlDbType.Int, 1),         new SqlParameter("@F_EditTime", SqlDbType.DateTime, 8) };      Params[0].Value = "TestUser1001";      Params[1].Value = "這是第一次測試";      Params[2].Value = 1;      Params[3].Value = DateTime.Now;      int count = SqlHelper.ExecuteNonQuery(strSql,Params,tran);      if (count > 0)      {        return true;      }      else      {        return false;      }    }    /// <summary>    /// 檢測Transaction    /// </summary>    /// <returns></returns>    public static bool InsertWithTran()    {      bool success = false;      string connectionString=System.Configuration.ConfigurationSettings.AppSettings["SqlConStr"].ToString();      using (SqlConnection con = new SqlConnection(connectionString))      {        con.Open();        SqlTransaction tran = con.BeginTransaction();        try        {           if (tran == null)          {            throw new Exception("Transaction is null");          }          if (InsertIntoUser(tran))          {            if (InsertIntoTitle(tran))            {              tran.Commit();              success = true;            }          }        }        catch        {          tran.Rollback();          success = false;        }        finally        {          tran.Dispose();          con.Close();        }      }      return success;    }  }

Button

 protected void Button1_Click(object sender, EventArgs e)  {    bool success = TestTransaction.InsertWithTran();    if (success)    {      Bmc.CLUtility.ShowMessage(this.Page, "插入成功");          }    else    {      Bmc.CLUtility.ShowMessage(this.Page, "插入失敗");    }  }

測試步驟

<1>運行程序

<2>將運行的地址,發給在同一個網段的同事,通過適當修改也能夠看到你運行的程序

<3>兩人都點擊按鈕,并查詢數據庫,看事務是否正確執行

<4>在事務中間創建斷點,主機點擊按鈕,并在斷點處中斷執行一段時間

<5>然后你們連接到數據庫,分別查詢表的數據,發現不能執行查詢操作。

<6>在同事機器點擊按鈕,查詢windows日志,發現了一些警告。這就證明了,事務在執行過程中,獨占資源

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 澄迈县| 朝阳县| 彩票| 新蔡县| 拉萨市| 错那县| 柘城县| 芜湖县| 麟游县| 吉林省| 黄石市| 南康市| 平阳县| 巍山| 定日县| 昌图县| 邢台市| 多伦县| 留坝县| 应用必备| 通山县| 夹江县| 游戏| 商河县| 乌鲁木齐县| 鄱阳县| 万源市| 渝中区| 云阳县| 开鲁县| 海兴县| 克拉玛依市| 右玉县| 聂拉木县| 南召县| 合山市| 黔江区| 增城市| 色达县| 丽水市| 廊坊市|