商業級程序離不開事務處理。例如向兩張關聯表同時插入數據:若無事務,第一表成功後數據庫異常導致第二表失敗,數據不一致。事務確保「要麼全成功,要麼全失敗」,維護數據一致性。
BEGIN TRAN
-- 操作 1
INSERT INTO Table1 ...
IF @@ERROR <> 0 GOTO On_Error
-- 操作 2
INSERT INTO Table2 ...
IF @@ERROR <> 0 GOTO On_Error
COMMIT TRAN
RETURN 0
On_Error:
ROLLBACK TRAN
RETURN -1
陷阱:若操作失敗但非致命錯誤(@@ERROR ≠ 0 但批次繼續),執行流會繼續到 COMMIT TRAN,系統提交已成功操作,導致部分更新——這就是「用了事務卻仍出現不一致」的原因。
正確做法:每個數據操作後立即檢查 @@ERROR,失敗立即跳轉錯誤處理執行 ROLLBACK。
表結構:
BBSUser(主表,ID 為 IDENTITY)
BBSUserAction(從表,UserID 引用主表 ID)
存儲過程 up_RegisterUser 利用 @@IDENTITY 獲取剛插入的自增 ID:
CREATE PROC up_RegisterUser
@a_strUserName VARCHAR(20), @a_strPassWord VARCHAR(10),
@a_strEmail VARCHAR(100), @a_strHomepage VARCHAR(100),
@a_strICQ VARCHAR(20), @a_strSignature VARCHAR(255),
@a_strIP VARCHAR(15)
AS
DECLARE @m_strUserID INT
BEGIN TRAN -- 事務開始
INSERT INTO BBSUser VALUES
(@a_strUserName, @a_strPassWord, 0, @a_strEmail,
@a_strHomepage, @a_strICQ, @a_strSignature, 0)
IF (@@ERROR <> 0) GOTO On_Error
SELECT @m_strUserID = @@IDENTITY -- 保存剛插入的 ID
INSERT INTO BBSUserAction VALUES
(@m_strUserID, GETDATE(), @a_strIP)
IF (@@ERROR <> 0) GOTO On_Error
COMMIT TRAN -- 事務結束
RETURN 0
On_Error:
ROLLBACK TRAN
RETURN -1
GO
要點:
1. 所有寫操作包裹在 BEGIN TRAN / COMMIT TRAN 內。
2. 每句 INSERT 後緊跟 IF @@ERROR <> 0 GOTO On_Error。
3. 利用 @@IDENTITY 獲取自增主鍵傳遞給從表。
4. 錯誤標簽統一 ROLLBACK 並返回錯誤碼。
事務處理核心在於「原子性」,關鍵在於逐句檢查 @@ERROR 並立即回滾。忽略此點是導致事務失效的首要原因。