c# 和 sqlserver 中的事務
sqlserver 中的事務
一提到事務,一般程序員對它的認識大概是這樣的:原子性,以一個整體來執行,要么全部執行,要么全部返回(回滾),這是一個最初級的認識,更深入一點的請看我另外一篇文章:http://www.cnblogs.com/mc67/p/4823514.html
今天我在這里做一下終結
- 自動提交事務:是SQL Server默認的一種事務模式,每條Sql語句都被看成一個事務進行處理,你應該沒有見過,一條Update 修改2個字段的語句,只修該了1個字段而另外一個字段沒有修改。。
- 顯式事務:T-sql標明,由Begin Transaction開啟事務開始,由Commit Transaction 提交事務、Rollback Transaction 回滾事務結束。
- 隱式事務:使用Set IMPLICIT_TRANSACTIONS ON 將將隱式事務模式打開,不用Begin Transaction開啟事務,當一個事務結束,這個模式會自動啟用下一個事務,只用Commit Transaction 提交事務、Rollback Transaction 回滾事務即可。
常用語句:
- Begin Transaction:標記事務開始。
- Commit Transaction:事務已經成功執行,數據已經處理妥當。
- Rollback Transaction:數據處理過程中出錯,回滾到沒有處理之前的數據狀態,或回滾到事務內部的保存點。
- Save Transaction:事務內部設置的保存點,就是事務可以不全部回滾,只回滾到這里,保證事務內部不出錯的前提下
BEGIN TRAN SET XACT_ABORT ON INSERT INTO TEST VALUES(1999,12,80) INSERT INTO TEST VALUES(1999,12,80) SET XACT_ABORT OFF COMMIT TRAN GO
或者你也可以這么寫滴呀
BEGIN TRANSACTION --你需要執行的更新,刪除,插入的語句 IF(@@ERROR > 0) //這是系統變量,存儲你在執行更新,刪除,插入操作時發生錯誤的記錄編號 ROLLBACK ELSE COMMIT
或者這........
BEGIN TRAN INSERT INTO TEST VALUES(1998,12,23) IF(@@ERROR<>0) --一旦報錯,這個就不等於0 了滴呀; ROLLBACK TRAN ELSE BEGIN INSERT INTO TEST VALUES(1998,12,23) IF(@@ERROR<>0) ROLLBACK ELSE COMMIT TRAN END
或者你可以這么寫
BEGIN TRY BEGIN TRAN INSERT TEST VALUES(1998,12,12) INSERT TEST VALUES(1998,12,'DF') COMMIT TRAN END TRY BEGIN CATCH ROLLBACK TRAN DECLARE @ERRMSG NVARCHAR(3000), @ERRLEVEL INT SELECT @ERRMSG=ERROR_MESSAGE(), @ERRLEVEL=ERROR_SEVERITY() RAISERROR(@ERRMSG,@ERRLEVEL,1) END CATCH
savepoint命令(在sql中為save tran或save transaction)
保存點是事務過程中的一個邏輯點,我們可以把事務回退到這個點,而不必回退整個事務。
在SQL Server中使用rollback會回滾所有的未提交事務狀態,但是有些時候我們只需要回滾部分語句,把不需要回滾的語句提到事務外面來,雖然是個方法,但是卻破壞了事務的ACID
BEGIN TRAN INSERT INTO TEST VALUES(1995,15,15) SAVE TRAN POINT1 INSERT INTO TEST VALUES(1995,15,15) ROLLBACK TRAN POINT1 COMMIT TRAN
結果只有一條數據插入進去滴呀;
或者我們可以舉一個更為 具體的是 列子;
測試代碼:
CREATE TABLE ACCOUNT ( ID INT PRIMARY KEY IDENTITY(1,1), NAME NVARCHAR(15), AMOUNT MONEY ) GO INSERT INTO ACCOUNT SELECT '劉奇',1300 UNION ALL SELECT '蔚藍',400
事務代碼:
BEGIN TRAN TRAN_MONEY --開始事務 DECLARE @TRAN_ERROR INT; SET @TRAN_ERROR=0; BEGIN TRY UPDATE ACCOUNT SET AMOUNT=AMOUNT-520 WHERE NAME='劉奇' SET @tran_error = @tran_error + @@ERROR; UPDATE ACCOUNT SET AMOUNT=AMOUNT+520 WHERE NAME='蔚藍' SET @tran_error = @tran_error + @@ERROR; END TRY BEGIN CATCH PRINT '出現異常,異常編號:'+CONVERT(VARCHAR,ERROR_NUMBER())+ '異常消息:'+ERROR_MESSAGE(); SET @TRAN_ERROR+=1; END CATCH IF(@TRAN_ERROR>0) BEGIN --有異常 回滾事務; ROLLBACK TRAN; PRINT '轉賬失敗,取消交易'; END ELSE BEGIN --沒有異常,提交事務 COMMIT TRAN; PRINT '轉賬成功!' END
ADO.NET中的事務
public static void ExecuteSQLTran(string sqlString) { using (SqlConnection con = new SqlConnection(conString)) { using (SqlCommand cmd = new SqlCommand(sqlString, con)) { con.Open(); SqlTransaction tran = con.BeginTransaction(); cmd.Transaction = tran; try { cmd.ExecuteNonQuery(); tran.Commit(); } catch (Exception e) { tran.Rollback(); } finally { con.Close(); } } } }
c# net framework 中的事務
TransactionScope是.Net Framework 2.0滯后,新增了一個名稱空間。它的用途是為數據庫訪問提供了一個“輕量級”[區別於:SqlTransaction]的事務。使用之前必須添加對 System.Transactions.dll 的引用
在.net 1.1的時代,還沒有TransactionScope類,因此很多關於事務的處理,都交給了SqlTransaction和SqlConnection,每個Transaction是基於每個Connection的。這種設計對於跨越多個程序集或者多個方法的事務行為來說,不是非常好,需要把事務和數據庫連接作為參數傳入。
在.net 2.0后,TransactionScope類的出現,大大的簡化了事務的設計。示例代碼如下:
static void Main(string[] args) { using (TransactionScope ts = new TransactionScope()) { userBLL u = new userBLL(); TeacherBLL t = new TeacherBLL(); u.ADD(); t.ADD(); ts.Complete(); } }
更多信息,請你參看:http://www.tuicool.com/articles/qaMzIb
還需要開啟.....
TransactionScopeOptions
描述
Required
如果已經存在一個事務,那么這個事務范圍將加入已有的事務。否則,它將創建自己的事務。
RequiresNew
這個事務范圍將創建自己的事務。
Suppress
如果處於當前活動事務范圍內,那么這個事務范圍既不會加入氛圍事務 (ambient transaction),也不會創建自己的事務。當部分代碼需要留在事務外部時,可以使用該選項。
您可以在代碼的任何位置上隨是查看是否存在事務范圍,具體方法就是查看 System.Transactions.Transaction.Current 屬性。如果這個屬性為“null”,說明不存在當前事務。
public static void transactionscopeSQL(string sqlString) { //設置配置信息 TransactionOptions options = new TransactionOptions(); options.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted; //設置事務隔離級別; options.Timeout = new TimeSpan(0,0,60); //設置超時時間; using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required,options)) { using (SqlConnection con = new SqlConnection(conString)) { SqlCommand cmd = new SqlCommand(sqlString,con); try { con.Open(); cmd.ExecuteNonQuery(); scope.Compelete(); } catch (Exception e) { } finally { scope.Dispose(); } } } }
更多事務信息:
http://wangqingpei557.blog.51cto.com/1009349/748799/