1.什麼是事務
1.1定義
事務就是被綁定在一起作爲一個邏輯工作單元的SQL語句組,如果任何一個語句操作失敗那麼整個操作就被失敗,進而回滾到操作前狀態,或者是上個節點。爲了確保要麼執行,要麼不執行,就可以使用事務。
1.2特性
- 原子性(atomicity) 一個事務是一個不可分割的工作單位,事務中包括的諸操作要麼都做,要麼都不做。
- 一致性(consistency) 事務必須是使數據庫從一個一致性狀態變到另一個一致性狀態。
- 隔離性(isolation) 一個事務的執行不能被其他事務干擾。即一個事務內部的操作及使用的數據對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾。
- 持久性(durability) 持續性也稱永久性(permanence),指一個事務一旦提交,它對數據庫中數據的改變就應該是永久性的。接下來的其他操作或故障不應該對其有任何影響。
1.3 幾種常見事務
- 自動提交事務: 是SQL Server默認的一種事務模式,每條Sql語句都被看成一個事務進行處理。比如一條Update 修改2個字段的語句,不會只修改一個字段而第二個字段沒有被修改。
- 顯示事務: 我們常用的事務,由Begin Transaction開啓事務開始,由Commit Transaction 提交事務、Rollback Transaction 回滾事務結束。
- 隱式事務: 使用Set IMPLICIT_TRANSACTIONS ON 將將隱式事務模式打開,不用Begin Transaction開啓事務,當一個事務結束,這個模式會自動啓用下一個事務,只用Commit Transaction 提交事務、Rollback Transaction 回滾事務即可。
2.事務的應用
2.1基本語句
- Begin Transaction: 開始事務。
- Rollback Transaction: 回滾事務,當數據處理中出錯時,回滾到沒有開始處理前的狀態,或者回滾到事務的保存點。
- Save Transaction: 保存點,事務回滾時不會全部回滾而是回滾到保存點處。
- Commit Transaction: 提交事務。
2.2 實例
2.2.1數據庫
USE [job]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Customers](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL,
[Country] [nvarchar](50) NULL,
[Sex] [bit] NULL,
[ConsumeAmount] [int] NULL,
[ConsumeLevel] [nvarchar](50) NULL,
[Remain] [decimal](18, 0) NULL,
CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Customers] WITH CHECK ADD CONSTRAINT [CK_Customers] CHECK (([remain]<(2000)))
GO
ALTER TABLE [dbo].[Customers] CHECK CONSTRAINT [CK_Customers]
GO
2.2.2代碼
--實現金額轉賬的功能
--爲了能使事務多次調用,用存儲過程來保存事務
--創建保存事務的存儲過程
create proc cp_remain
(
@idIn int, --轉賬人ID
@idOut int, --接收人ID
@money decimal(18, 0) --轉賬金額
)
as
--事務的語法
BEGIN TRAN Tran_Money --開始事務
--定義變量用於記錄錯誤數
DECLARE @tran_error int;
SET @tran_error = 0;
BEGIN TRY
UPDATE Customers SET Remain = Remain - @money WHERE ID=@idIn --將轉賬人的金額減少
SET @tran_error = @tran_error + @@ERROR; --記錄錯誤數
UPDATE Customers SET Remain = Remain + @money WHERE ID=@idOut --將接收人的金額增加
SET @tran_error = @tran_error + @@ERROR; --記錄錯誤數
END TRY
--如果處理數據中有失敗就執行裏面的代碼
BEGIN CATCH
PRINT '出現異常,錯誤編號:' + convert(varchar,error_number()) + ',錯誤消息:' + error_message()
SET @tran_error = @tran_error + 1
END CATCH
IF(@tran_error > 0)
BEGIN
--執行出錯,回滾事務
ROLLBACK TRAN;
PRINT '轉賬失敗,取消交易!';
END
ELSE
BEGIN
--沒有異常,提交事務
COMMIT TRAN;
PRINT '轉賬成功!';
END