ADO.NET系列之Connection對象 ADO.NET系列之Command對象 ADO.NET系列之DataAdapter對象 ADO.NET系列之事務和調用存儲過程 前幾篇我們介紹了Connection、Command和DataAdapter等對象,本節我們將學習ADO.NET中不可缺少的事 ...
前幾篇我們介紹了Connection、Command和DataAdapter等對象,本節我們將學習ADO.NET中不可缺少的事務,以及調用資料庫的存儲過程。
ADO.NET事務
在許多大型、關鍵的應用程式中,電腦每秒鐘都在執行大量的任務。更為經常的不是這些任務本身,而是將這些任務結合在一起完成一個業務要求,稱為事務。如果能成功地執行一個任務,而在第二個或第三個相關的任務中出現錯誤,將會發生什麼?這個錯誤很可能使系統處於不一致狀態。這時事務變得非常重要,它能使系統擺脫這種不一致的狀態。
一個Command對象的CommandText屬性指定多條以;分割的語句。這種情況下若沒有事務,所有的語句都會被執行,若其中有語句出錯,就導致了數據的不一致性。當然我們也可以寫存儲過程,在SQLServer的資料庫系統內建存儲過程的語句若沒有事務,多條語句中的部分語句失效,一樣導致數據的不一致性:你可以在存儲過程內部Try/Catch/BeginTransaction等。
事務是一個最小的工作單元,不論成功與否都作為一個整體進行工作。詳情可參考:http://www.cnblogs.com/windows/articles/1605638.html
下麵我們做個示例展示事務在ADO.NET中的使用方法。
string connectionString = "Data Source=.;Initial Catalog=ax_log;User Id=sa;Password=sa123;"; using (SqlConnection con = new SqlConnection(connectionString)) { con.Open(); using (SqlTransaction tran = con.BeginTransaction()) { using (SqlCommand com = con.CreateCommand()) { try { com.Transaction = tran; com.CommandText = "insert into table values('1','111')"; com.ExecuteNonQuery(); com.CommandText = "insert into table values('2','222')"; com.ExecuteNonQuery(); tran.Commit(); Console.WriteLine("事務提交成功"); } catch (SqlException ex) { tran.Rollback(); con.Close(); Console.WriteLine("事務提交失敗:" + ex.Message); } } } }
Connection對象BeginTransaction啟動事務,然後將事務賦值給Command對象的Transaction屬性即掛接了事務。即使沒有Commit 和Rollback,若執行中 錯誤,事務一樣自動回滾,或者成功提交。
BeginTransaction可以指定隔離級別。ReadXXX不會對資料庫加鎖,儘管在事務中,外部程式仍然可以讀取數據;但若事務中有Update語句,將導致資料庫鎖,外部程式不能繼續讀取數據。
儘量考慮在存儲過程中使用事務,避免使用ADO的事務,因為ADO的事務可能導致資料庫長時間處於鎖定狀態;而資料庫內的存儲過程中的事務往往不會長時間掛起事務。
ADO.NET調用存儲過程
存儲過程(Stored Procedure)是一組為了完成特定功能的T-SQL語句集合,經編譯後存儲在SQL Server伺服器中,利用存儲過程可以加速SQL語句的執行。
在應用程式中,使用存儲過程讀取數據,能夠提高應用程式的工作效率,簡化資料庫的管理和顯示信息
創建一個帶有輸入參數的存儲過程:
CREATE PROCEDURE GetUserPro @id INT AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; SELECT * FROM dbo.eftest WHERE id=@id END GO
ADO.NET中調用存儲過程示例:
string connectionString = "Data Source=.;Initial Catalog=ax_log;User Id=sa;Password=sa123;"; using (SqlConnection con = new SqlConnection(connectionString)) { string sql = "GetUserPro"; SqlParameter para = new SqlParameter("@id", 1); using (SqlCommand com = new SqlCommand(sql, con)) { DataSet ds = new DataSet(); try { com.Parameters.Add(para); con.Open(); com.CommandType = CommandType.StoredProcedure; SqlDataAdapter adapter = new SqlDataAdapter(com); adapter.Fill(ds); foreach (DataRow s in ds.Tables[0].Rows) { Console.WriteLine("ID:" + s["id"].ToString()); Console.WriteLine("Name:" + s["name"].ToString()); } } catch (Exception ex) { } } }
看過Command對象介紹的時候,代碼跟那個差不多 ,是的 比Command章節的代碼就多了一行:com.CommandType = CommandType.StoredProcedure; CommandType 預設情況是:com.CommandType = CommandType.Text;CommandType.StoredProcedure表示執行存儲過程。