|
最近看了一下事務(wù),記點(diǎn)東西。 使用的表結(jié)構(gòu)如下: USE [TestDB]
GO /****** 對(duì)象: Table [dbo].[Person] 腳本日期: 11/23/2008 13:37:48 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Person]( [PersonId] [nchar](18) NOT NULL, [PersonName] [nchar](20) NOT NULL, CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED ( [PersonId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] 默認(rèn)情況下如果執(zhí)行一個(gè)事務(wù)中出現(xiàn)錯(cuò)誤,則只回滾錯(cuò)誤操作語句(就是說這句不執(zhí)行了,算不上回滾),錯(cuò)誤處之前或之后的正確操作語句還是會(huì)被提交。如: Use TestDB
Begin TransAction Insert Into Person(PersonId,PersonName) Values('1','Name1') Insert Into Person(PersonId,PersonName) Values('1','Name1') Insert Into Person(PersonId,PersonName) Values('3','Name3') Commit TransAction /* Select 一下 有'1','Name1'和'3','Name3', 說明只有第二句的錯(cuò)誤被取消了 */ 全部回滾的方法1:打開 XACT_ABORT Use TestDB
SET XACT_ABORT ON -- 打開 Begin TransAction Insert Into Person(PersonId,PersonName) Values('1','Name1') Insert Into Person(PersonId,PersonName) Values('1','Name1') Insert Into Person(PersonId,PersonName) Values('3','Name3') Commit TransAction /* 當(dāng) SET XACT_ABORT 為 ON 時(shí), 如果執(zhí)行 Transact-SQL 語句產(chǎn)生運(yùn)行時(shí)錯(cuò)誤, 則整個(gè)事務(wù)將終止并回滾。 默認(rèn)情況下它是OFF狀態(tài)。 */ 全部回滾方法2:使用Try...Catch Use TestDB
Begin Try Begin TransAction Insert Into Person(PersonId,PersonName) Values('1','Name1') Insert Into Person(PersonId,PersonName) Values('1','Name1') Insert Into Person(PersonId,PersonName) Values('3','Name3') Commit TransAction End Try Begin Catch Rollback TransAction End Catch /* 使用Try Catch來捕獲異常。如果 TRY 塊內(nèi)生成的錯(cuò)誤導(dǎo)致當(dāng)前事務(wù)的狀態(tài)失效, 則將該事務(wù)歸類為不可提交的事務(wù)。 如果通常在 TRY 塊外中止事務(wù)的錯(cuò)誤在 TRY 內(nèi)發(fā)生時(shí), 就會(huì)導(dǎo)致事務(wù)進(jìn)入不可提交狀態(tài)。 不可提交的事務(wù)只能執(zhí)行讀操作或 ROLLBACK TRANSACTION。 該事務(wù)不能執(zhí)行任何可能生成寫操作或 COMMIT TRANSACTION 的 Transact-SQL 語句。 如果事務(wù)被分類為不可提交的事務(wù),則 XACT_STATE 函數(shù)會(huì)返回值 -1。 */ 全部回滾方法3:自定義錯(cuò)誤變量 Use TestDB
Declare @tranError int -- 定義變量 Set @tranError=0 Begin TransAction Insert Into Person(PersonId,PersonName) Values('1','Name1') Set @tranError = @tranError + @@Error Insert Into Person(PersonId,PersonName) Values('1','Name1') Set @tranError = @tranError + @@Error Insert Into Person(PersonId,PersonName) Values('3','Name3') Set @tranError = @tranError + @@Error If @tranError = 0 Commit TransAction Else Rollback TransAction /* 自定義一個(gè)變量來判斷最后是否發(fā)生過錯(cuò)誤。 */ 最后要注意的是:如果一個(gè)事務(wù)寫了 Begin TransAction 而沒寫 Commit TransAction 或 Rollback TransAction 則相關(guān)操作的數(shù)據(jù)(也許是表,也許是列,這我還沒測(cè)試。。。)會(huì)被鎖住。。。而對(duì)于鎖住的解決辦法就是單獨(dú)執(zhí)行一下Commit TransAction 或 Rollback TransAction |
|
|