sql事務的使用及其技巧整理
概述:
在實際專案開發中,為了確保資料操作結果的一致性等要求,事務是一個必不可少的解決利器,
根據SQLSERVER實作原理,其實,SQLSERVER的每一條執行陳述句都是一個事務操作,也就是說每一個SQL陳述句要么操作都成功,要么操作都失敗:比如,更新陳述句,同時更新多個欄位,不會出現有的欄位更新成功,有的欄位更新失敗,
但是,我們平時在開發程序程序中,說的事務:其實是指的一組有序的SQL集合,通過事務確保這一組SQL集合執行結果的一致性,
事務特性:
事務的主要特性包括:原子性、一致性、隔離性、持久性
- 原子性:事務必須是一個自動作業的單元,要么全部執行,要么全部不執行,
- 一致性:事務把資料庫從一個一致狀態帶入到另一個一致狀態,事務結束的時候,所有的內部資料都是正確的,
- 隔離性:并發多個事務時,一個事務的執行不受其他事務的影響,
- 持久性:事務提交之后,資料是永久性的,不可再回滾,不受關機等事件的影響
事務分類:
根據事務的執行維度力度,事務又分為:自動提交事務、顯式事務、隱式事務
自動提交事務:sqlserver的一種默認機制,也叫自身事務,每一個sql陳述句執行都是采用的這種模式
顯式事務:這也是我們平時常說的事務, 通過 Begin Transaction開啟事務開始,執行一組SQL陳述句,由Commit Transaction 提交事務、Rollback Transaction 回滾事務結束,
隱式事務:使用Set IMPLICIT_TRANSACTIONS ON 將隱式事務模式打開,sql執行完畢自動提交,當一個事務結束,這個模式會自動啟用下一個事務,只用Commit Transaction 提交事務、Rollback Transaction 回滾事務即可
顯示事務和隱式的主要區別自在于,隱式事務在執行完畢后自動提交,
顯式事務使用簡介:
顯示事務通過begin Transaction 開啟事務,通過Rollback Transaction 回滾事務
資料準備,首先創建一個表:
---- 創建一個表TEST_Name ,每一個欄位都是非空CREATE TABLE [dbo].[TEST_Name]( [Id] [int] NULL, [Name] [nvarchar](50) NULL) ON [PRIMARY]
實體:
---- 正常完整的執行一個事務,且事務內SQL無例外
---- 正常完整的執行一個事務,且事務內SQL無例外begin traninsert into TEST_name values(1,1)insert into TEST_name values(3,3)commit tran
---- 執行一個事務,且事務內SQL有例外
begin traninsert into TEST_name values(10,10)insert into TEST_name values(11,null)----次陳述句執行失敗,原因是該name不允許為空insert into TEST_name values(12,12)commit tran
----- 陳述句最終執行結果是
成功插入id為:10、12的兩條資料
通過上面的陳述句,這樣的執行結果和我們事務中的一致性相違背,這不是我們使用事務想要看到的效果,其實我們希望的是這3個陳述句要么都插入成功,要么都插入失敗
為了達到資料,可以通過以下三種方式來實作:try catch;執行結果判斷,一步一步執行,錯誤回滾;開啟 xact_abort(精準終止)
try catch 實作事務回滾
begin tranbegin try insert into TEST_name values(1,1) insert into TEST_name values(2,null) insert into TEST_name values(3,2) commit tranend trybegin catch select '執行例外,事務回滾' rollback tranend catch
---- 執行結果是:不會插入一條資料
執行結果判斷,一步一步執行,錯誤回滾
begin tran declare @error int set @error=0 insert into TEST_name values(1,1) set @error=@error+@@error insert into TEST_name values(2,null) set @error=@error+@@error insert into TEST_name values(3,2) set @error=@error+@@error if(@error<>0) begin select '執行例外,事務回滾' rollback tran endelse begin commit tran end
---- 每一步執行結果都正確才繼續往下執行begin tran ---- 影響行數 declare @ROWCOUNT int set @ROWCOUNT=0 insert into TEST_name values(1,1) set @ROWCOUNT=@@ROWCOUNT if(@ROWCOUNT>0) begin insert into TEST_name values(2,null) set @ROWCOUNT=@@ROWCOUNT end if(@ROWCOUNT>0) begin insert into TEST_name values(3,2) set @ROWCOUNT=@@ROWCOUNT end if(@ROWCOUNT<=0) begin select '執行例外,事務回滾' rollback tran endelse begin commit tran end
開啟 xact_abort(精準終止)
---- XACT_ABORT 設定 on :代表某一個陳述句執行錯誤,都不在繼續往下執行,并自動回滾事務
---- XACT_ABORT 設定 off :代表某一個陳述句執行錯誤,子回滾該條陳述句執行,并繼續執行后續陳述句,同時提交執行成功的陳述句
---- off 此種情況應該很少在事務中使用,畢竟使用事務的目的就是實作執行結果的一致性
set XACT_ABORT onbegin traninsert into TEST_name values(10,10)insert into TEST_name values(11,null)----次陳述句執行失敗,原因是該name不允許為空insert into TEST_name values(12,12)commit tran
設定事務保存點:
在平時的事務使用程序中,還有可能需要實作,事務回滾時,只回滾到指定位置,指定位置之前的執行結果不在回滾
在sqlserver中可以通過事務保存點,來實作對事務的精確回滾,關鍵詞是:save transaction 和rollback transaction ,具體使用規則如下:
---- 每一步執行結果都正確才繼續往下執行begin tran ---- 影響行數 declare @ROWCOUNT int set @ROWCOUNT=0 insert into TEST_name values(1,1) set @ROWCOUNT=@@ROWCOUNT save tran stanstation1 --- save tran transtation1 if(@ROWCOUNT>0) begin insert into TEST_name values(2,null) set @ROWCOUNT=@@ROWCOUNT end if(@ROWCOUNT>0) begin insert into TEST_name values(3,2) set @ROWCOUNT=@@ROWCOUNT end if(@ROWCOUNT<=0) begin select '執行例外,事務回滾' ---- 執行結果是:1,1 成功插入到資料庫表中 rollback tran stanstation1 endelse begin select '事務提交' commit tran end
總結:
通過上面的溫習,結合練習,對sql的事務有了進一步的了解,簡單的總結:實際上執行的每一個sql都是采用事務來實作的,在實際使用中,我們一般采用顯示事務來處理業務,但是在事務的使用程序中一定要結合對應的策略來確保事務執行結果的一致性,
今天就寫到這,明天再簡單那梳理總結一下分布式事務的實作方式,這個也是很重要的模塊,尤其是在現在的大型系統中,分庫分表時,分布式事務很管用
xact_abort
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/8120.html
標籤:ASP.NET
上一篇:專案需求,也擼個審批流程的玩意
