青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

黎明的剔透里伸出了你沁清的曖昧

Graphics|EngineDev|GameDev|2D&3D Art

  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
  60 隨筆 :: 1 文章 :: 18 評論 :: 0 Trackbacks

如果在數據庫發生更換的情況下,只需要修改配置文件的數據提供程序名稱這一行即可事務

       事務是一組必須全部成功或者全部失敗的操作。事務的目標是保證數據總能處于有效一致的狀態。例如,轉賬操作。

 

       事務有 4 個被稱為 ACID 屬性的特征,ACID 是以下概念的縮寫:

  • Atomic(原子性):事務中所有步驟必須同時成功或失敗
  • Consist(一致性):事務使底層數據庫在穩定狀態間轉換
  • Isolated(隔離性):每個事務都是獨立的實體,一個事務不應該影響同時運行的其他事物。
  • Durable(持久性):在事務成功前,事務產生的變化永久的存儲在媒質上,同時也必須維護日志以保證出現硬件故障數據庫也能得以恢復。

       這些事事務的理想特征,它們未必總能達到。執行事務時 RDBMS 需要鎖定數據,這樣其他用戶就不能訪問它了。鎖越多,粒度就越大,執行事務時其他用戶就更不可能完成某些任務。也就是說,需要在用戶并發性和隔離性間做出權衡

 

 

事務和 ASP.NET 應用程序

       ASP.NET 可以使用 3 種基本類型的事務:

  • 存儲過程事務:這些事務完全在數據庫中處理,存儲過程事務提供最佳的性能,因為只需往返一次數據庫。缺點是需要用 SQL 語句編寫事務處理邏輯
  • 客戶端引發(ADO.NET)的事務這些事務由代碼通過編程來控制。它們使用和存儲過程事務一樣的命令,代碼使用了封裝這些細節的 ADO.NET 對象。缺點是在事務開始和提交時需要額外往返數據庫
  • COM+ 事務:COM+ 采用兩步提交協議,總會帶來額外開銷。只有當事務需要跨越多個資源管理器的時候才需要使用 COM+事務。一個COM+可以跨越 SQL Server 及 Oracle 數據庫中的交互。

 

       盡管ADO.NET提供對事務的良好支持,但還是不應該隨便使用。每次使用都會為系統帶來額外的負擔。另外,事務會鎖定表的某些行,不必要的事務會損害你的應用程序性能。

       使用事務應遵循這些實踐原則以獲得最佳效果:

  • 事務要盡量短
  • 不要在事務中間使用 SELECT 查詢返回數據
  • 如果事務中確實要獲取記錄,應該只獲取確實需要的記錄,這樣可以減少鎖定的資源數
  • 可能的情況下,在存儲過程中使用事務,而不是在 ADO.NET 中使用事務。這樣的事務可以被更快的啟動和編譯,因為數據庫服務器不需要與客戶端(Web 應用程序)交互。
  • 避免使用具有多個獨立批處理任務的事務,把各個批處理任務作為單個事務
  • 盡量避免影響大批量記錄的更新

 

1. 存儲過程事務

       只要可能,事務存放的最佳地點是存儲過程代碼。它最有可能獲得最佳性能,所有的活動在數據源進行而不需要任何網絡通信。總之,事務的跨度越短,數據庫的并發性越好,被序列化的數據庫請求就越少

       下面這段偽代碼演示了如何在兩個賬戶間轉移資金,它是一個簡化的版本,允許賬戶村礦為負數:

CREATE Procedure TransferAmount
(
    @Amount Money,
    @ID_A int,
    @ID_B int
)
as
    begin transaction
    update Accounts set balance = balance + @Amount where AccountID = @ID_A
    if(@@error > 0)
        GOTO Problem
    update Accounts set balance = balance - @Amount where AccountID = @ID_B
    if(@@error > 0)
        GOTO Problem
 
-- 沒有錯誤
    commit
    return
 
-- 有錯誤
Problem:
    rollback
    raiserror('Could not update.',16,1)    

      當在 Transact-SQL 中使用 @@error 值時,必須在每步操作完成后立即檢查該值!!!因為 @@error 在一條 SQL 語句成功執行后自動被重設為 0 。

 

       如果使用 SQL Server2005 或更新的版本,有一個更為現代的 try/catch 結構的優勢來實現上面的示例。(GOTO 語句畢竟非議頗多)

CREATE Procedure TransferAmount
(
    @Amount Money,
    @ID_A int,
    @ID_B int
)
as
    begin try
        begin transaction
            update Accounts set balance = balance + @Amount where AccountID = @ID_A
            update Accounts set balance = balance - @Amount where AccountID = @ID_B
            -- 出錯會進入 catch 塊,這里可以直接提交
            commit
    end try
    
    begin catch
        if(@@trancount > 0)
            rollback
        
        -- 記錄異常信息
        declare @ErrMsg nvarchar(4000),@ErrSeverity int
        select @ErrMsg = ERROR_MESSAGE(),@ErrSeverity = ERROR_SEVERITY()
        raiserror(@ErrMsg,@ErrSeverity,1)
    end catch

       這個示例檢查 @@trancount 以確定是否有事務在進行中。(變量 @@trancount 計算當前連接中進行的事務數,begin transaction 語句使之加1,而 rollback 和 commit 使之減1 。)

       為了防止錯誤被 catch 塊吞噬,使用了 raiserror 語句。 ADO.NET 把該消息封裝成 SqlException 對象,后者需要你在 .NET 中進行捕獲。

 

2. 客戶端引發的 ADO.NET 事務

       大多數 ADO.NET 數據提供程序都提供對數據庫事務的支持。

       Transaction 類有兩個關鍵方法:

  • Commit()
  • Rollback()

       下面這個示例演示向 Employees 表中插入兩條記錄:

protected void Page_Load(object sender, EventArgs e)
{
    string connStr = WebConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
    SqlConnection conn = new SqlConnection(connStr);
 
    SqlCommand cmd1 = new SqlCommand("insert into Employees(LastName,FirstName) values('Joe','Tester')", conn);
    SqlCommand cmd2 = new SqlCommand("insert into Employees(LastName,FirstName) values('Harry','Sulivan')", conn);
    SqlTransaction tran = null;
 
    try
    {
        // Open the connection and create the transaction
        conn.Open();
        tran = conn.BeginTransaction();
 
        // Enlist two commands in the transaction
        cmd1.Transaction = tran;
        cmd2.Transaction = tran;
 
        // Execute both commands
        cmd1.ExecuteNonQuery();
        cmd2.ExecuteNonQuery();
 
        // Commit the transaction
        tran.Commit();
    }
    catch
    {
        // In the case of error,rool back the transaction
        tran.Rollback();
    }
    finally
    {
        conn.Close();
    }
}

       僅僅創建和提交事務是不夠的,一定要設置 Command.Transaction 屬性為 Transaction 對象從而把 Command 對象顯式的列入事務中,事務進行中執行一個不在當前事務中的命令,會產生錯誤。

 

事務的隔離級別

       隔離級別決定了事務對其他事務影響的數據的敏感度。默認情況下,當兩個事務獨立運行時,在第一個事務結束前,第一個事務插入的數據對其他事務不可見。

       隔離級別的概念和鎖的概念緊密相關,因為確定事務的隔離級別就是確定所需的鎖的類型

  • 共享鎖:是事務讀取數據庫中的數據時產生的鎖。當表,行,或某個范圍內有共享鎖時,其他事務就不可用修改相應的數據,但多個用戶可以使用共享鎖并發讀取數據。
  • 獨占鎖:禁止多個事務同時修改數據。當事務更新數據且沒有其他事物已經鎖定數據的同時,會產生獨占鎖。當有獨占鎖時,其他用戶不能讀取或更新數據。

       在 SQL Server 存儲過程中,使用 SET   TRANSACTION   ISOLATION   LEVEL 命令來設置隔離級別。在 ADO.NET 中,可向 Connection.BeginTransaction()方法傳入 IsolationLevel 枚舉值,見下表:

ReadUncommitted無共享鎖,也不會有獨占鎖。會導致臟數據讀,但可以提升性能。
ReadCommitted數據被事務讀時會產生共享鎖,避免了臟數據讀,但數據在事務結束前可能已經被修改,這樣可能會產生非重復讀虛幻行。(SQL Server 默認隔離級別)
Snapshot保存一份事務正在訪問的數據的副本,因此一個事務不會看到其他事務所做的修改。這個隔離級別減少了堵塞,因為當其他事務正在讀取被快照隔離事務鎖鎖定的數據時,它可以從數據副本中讀取數據。該選項僅被 SQL Server 2005 支持,而且需要通過數據庫級別的設定才能夠啟用。
RepeatableRead查詢中涉及的所有數據均被加上共享鎖。這樣避免了他人修改數據,同時也避免了不可重復的讀,還是可能會出現虛幻行。
Serializable在所使用的數據上的一系列鎖禁止了其他用戶在該范圍內更新或插入行。它是唯一可以刪除虛幻行的隔離級別,但是給并發訪問帶來非常消極的影響,多用戶場景中很少使用。

       相關的數據庫術語

  • 臟讀:讀取了其他尚未提交的事務中的數據,但該事務可能被回滾
  • 不可重復讀:如果允許不可重復讀,那么在同一個事務中執行多次查詢可能會得到不同的數據。這是因為事務在進行過程中只讀取數據并不能阻止其他用戶修改數據。為了防止不可重復讀,數據庫服務器需要鎖定事務讀取的行。
  • 虛幻行:指在初始讀取中沒有出現但在相同事務內后續讀取時出現的行。事務進行過程中其他用戶插入了記錄,就可能出現幻行。為了防止幻行,事務進行過程中查詢數據庫時要根據 WHERE 子句使用一個范圍鎖。

       這些現象究竟是無害的小缺陷還是潛在的錯誤取決于你的特定需求。大多數情況下,不可重復讀和幻行只是小問題,使用鎖阻止它們發生并發的代價有點太高了,不太值得。ReadCommitted 對于大多數事務都適用。看一下不同隔離級別的對比:

隔離級別

臟  讀

不可重復讀

虛幻數據

并發性

未提交讀(Read uncommitted)

最佳

提交度(Read committed)

快照(Snapshot)

重復讀(Repeatable read)

一般

序列化(Serializable)

最差

 

 

數據提供程序無關的代碼

創建工廠

       工廠模型的基本思想是借助一個單一的工廠對象創建所有需要使用的提供程序相關的對象。然后就可以通過一組共同的基類以完全通用的方式與這些提供程序相關的對象交互。

       有一個動態發現并創建你需要的工廠的標準類,這個類是 System.Data.Common.DbProviderFactories 。它提供了一個 GetFactory()方法,這個方法根據提供程序的名字返回相應的工廠。

string factory = "System.Data.SqlClient"; 
DbProviderFactory provider = DbProviderFactories.GetFactory(factory);

       所有的工廠都是繼承自 DbProviderFactory 的,如果你只是用 DbProviderFactory 的成員,你編寫的代碼就可以喝其他工廠一起正常使用。前面代碼的不足在于傳遞的提供程序名稱的字符串,通常這應該配置在 web.config 中。

       要使 DbProviderFactory 類正常工作,提供程序要有一個在 machine.config 或 web.config 中注冊過的工廠。

 

用工廠創建對象

       再次強調,你必須假設你不知道正在使用的提供程序,這樣你就只能通過標準的基類來與工廠所創建的對象交互。一個簡單的示例可以幫助你更好的裂解這些零碎的概念是如何協作的。

       在 web.config 文件中為示例配置 連接字符串,提供程序名稱,以及查詢語句:

<configuration>
  <connectionStrings>
    <add name="Northwind" connectionString="Data Source=localhost;Initial Catalog=Northwind;Integrated Security=SSPI"/>    
  </connectionStrings>
  <appSettings>
    <add key="factory" value="System.Data.SqlClient" />
    <add key="employeeQuery" value="select * from employees" />
  </appSettings>
</configuration>

       基于工廠的代碼:

protected void EmployeesQuery()
{
    // Get the factory
    string factory = WebConfigurationManager.AppSettings["factory"];
    DbProviderFactory provider = DbProviderFactories.GetFactory(factory);
 
    // Use this factory to create a connection
    DbConnection conn = provider.CreateConnection();
    conn.ConnectionString = WebConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
 
    // Create the command
    DbCommand cmd= provider.CreateCommand();
    cmd.Connection = conn;
    cmd.CommandText = WebConfigurationManager.AppSettings["employeeQuery"];
 
    // Open the connection and get the DataReader
    conn.Open();
    DbDataReader reader = cmd.ExecuteReader();
}     
如果在數據庫發生更換的情況下,只需要修改配置文件的數據提供程序名稱這一行即可
 

posted on 2015-12-06 16:45 情絕格調(fresmaster) 閱讀(663) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            免费久久精品视频| 亚洲高清资源| 欧美日韩国产色视频| 亚洲国产成人久久综合| 亚洲第一网站| 国产一区欧美| 亚洲在线观看免费| 亚洲黄色影片| 欧美交受高潮1| 99国产精品99久久久久久| 国产精品一区三区| 亚洲影视在线| 最近中文字幕mv在线一区二区三区四区| 午夜精品视频网站| 亚洲国产精品久久久久秋霞影院| 久久精品二区亚洲w码| 亚洲裸体视频| 一区二区三区视频在线看| 国产一区二区三区在线观看免费视频 | 亚洲国产成人在线| 亚洲精选视频免费看| 午夜日韩av| 久久精品视频在线看| 国产精品羞羞答答xxdd| 亚洲免费小视频| 欧美激情中文字幕一区二区| 久久只精品国产| 国产精品入口福利| 日韩一区二区久久| 欧美成人精品三级在线观看| 在线 亚洲欧美在线综合一区| 亚洲深夜av| 亚洲免费观看视频| 亚洲精品字幕| 亚洲欧美另类久久久精品2019| 99国产精品久久| 一区二区欧美日韩| 亚洲国产天堂久久国产91| 欧美激情一区二区| 在线观看亚洲精品| 激情文学一区| 欧美精品一区在线播放| 欧美日韩综合视频| 亚洲国产精品激情在线观看| 免费观看成人| 国产色爱av资源综合区| 欧美电影电视剧在线观看| 欧美日韩一二区| 国产亚洲美州欧州综合国| 亚洲人成网站在线播| 性色一区二区| 9l视频自拍蝌蚪9l视频成人| 99精品欧美一区二区三区 | 欧美日韩精品二区第二页| 欧美xart系列高清| 日韩视频在线一区二区| 一区二区欧美国产| 亚洲欧美日韩国产一区二区| 亚洲午夜在线观看| 99国产精品久久久| 亚洲三级电影全部在线观看高清| 久久久久久久久久久久久久一区 | 久久久久久网| 狠狠v欧美v日韩v亚洲ⅴ| 在线不卡亚洲| 午夜免费日韩视频| 亚洲精品久久| 午夜精品999| 久久精品亚洲| 亚洲大片av| 99热这里只有精品8| 美女诱惑一区| 亚洲丶国产丶欧美一区二区三区| 亚洲国内在线| 亚洲欧美国产视频| 亚洲国产精品一区二区三区| 毛片基地黄久久久久久天堂| 亚洲激情视频网| 亚洲女同精品视频| 欧美日韩99| 亚洲第一搞黄网站| 国产日韩欧美三区| 一区二区免费在线播放| 久久亚洲精选| 亚洲国产激情| 蜜桃伊人久久| 亚洲激情欧美激情| 亚洲国产高清在线| 欧美成人亚洲| 欧美日韩成人一区二区三区| 又紧又大又爽精品一区二区| 国产精品免费观看在线| 日韩视频免费观看| 99热这里只有成人精品国产| 欧美视频你懂的| 在线综合+亚洲+欧美中文字幕| 欧美在线观看网址综合| 亚洲欧洲一区二区三区| 久久亚洲综合网| 国产一区二区三区日韩欧美| 性欧美精品高清| 亚洲黄一区二区| 亚洲天天影视| 欧美日韩国产一级片| 在线视频欧美精品| 亚洲欧美久久| 亚洲福利国产| 亚洲免费电影在线| 中文欧美字幕免费| 国产精品久久久久毛片大屁完整版 | 国产色视频一区| 亚洲一区二区三区国产| 一区二区日韩伦理片| 一区二区三区精品久久久| 伊人久久亚洲美女图片| 亚洲欧洲在线看| 久久久午夜精品| 久久久噜久噜久久综合| 亚洲日韩第九十九页| 欧美国产日韩精品| 亚洲国产精品www| 久久久久欧美精品| 亚洲视频福利| 欧美不卡在线视频| 欧美69视频| 亚洲综合成人婷婷小说| 国产日韩在线一区| 国产精品福利久久久| 欧美mv日韩mv国产网站| 亚洲欧美卡通另类91av | 欧美极品欧美精品欧美视频| 另类成人小视频在线| 亚洲国产你懂的| 99热这里只有精品8| 亚洲欧美一区二区在线观看| 久久九九久精品国产免费直播| 免费一级欧美片在线观看| 久久香蕉国产线看观看网| 亚洲精品欧美一区二区三区| 亚洲日本中文字幕| 亚洲欧美日韩综合一区| 亚洲欧美日韩天堂| 中文在线资源观看网站视频免费不卡| 欧美一级专区免费大片| 国产精品久久福利| 国产农村妇女毛片精品久久麻豆| 国产精品一区二区在线| 一本到12不卡视频在线dvd| 欧美一区二区三区四区视频| 亚洲国产欧美不卡在线观看| 欧美日韩国产一区| 国产精品va在线| 在线成人激情| 亚洲香蕉在线观看| 亚洲一二三级电影| 欧美精品一级| 欧美黑人在线播放| 亚洲高清视频一区二区| 久久在线视频在线| 国产精品爱啪在线线免费观看| 亚洲国产精品成人综合色在线婷婷 | 免费观看成人www动漫视频| 91久久精品网| 免费一级欧美片在线观看| 欧美一区二区三区免费看| 一本色道久久加勒比88综合| 亚洲福利精品| 国产精品一区毛片| 欧美精品在线免费| 亚洲女同精品视频| 亚洲影院高清在线| 亚洲天堂av在线免费观看| 欧美自拍偷拍午夜视频| 亚洲一区二区三区免费观看| 欧美搞黄网站| 欧美精品亚洲| 欧美色123| 久久不射中文字幕| 久久精品毛片| 午夜精品一区二区三区电影天堂| 亚洲视频欧美在线| 亚洲欧美经典视频| 亚洲综合色噜噜狠狠| 国产日韩在线亚洲字幕中文| 国产在线精品一区二区夜色| 性欧美暴力猛交69hd| 久久国产精品99国产精| 久久综合色88| 中文av字幕一区| 亚洲欧美网站| 99亚洲一区二区| 亚洲综合国产精品| 欧美有码视频| 亚洲国产mv| 亚洲精品国产视频| 一区二区三区欧美在线观看| 亚洲国产精品小视频| 亚洲精品久久久久久久久| 久久精品免视看| 欧美国产日韩一区二区三区|