SQLServer 內部事務與外部事務的統一

2022-09-08 08:27:11 字數 1573 閱讀 3417

在我們日常資料庫開發過程中,涉及到資料增刪改,無一例外都需要使用事務來控制其一致性。

而對於業務邏輯比較複雜的erp/mes/wms等系統來說,一致性尤其重要。

此時我們考慮乙個問題,儲存過程a開啟了事務,此時b由於業務需要呼叫儲存過程a,但是b又有自己的業務,也需要開啟事務。此時我們就需要考慮事務的一致。

而受sqlserver的事務機制影響,在第一次commit之後,事務計數就會重新,等到我們commit第二個事務的時候就會報錯:execute後的事務計數指示begincommit語句的數目不匹配。上一計數 = 1,當前計數 = 0。

除了巢狀這一種比較麻煩的方式之外,還有另外一種更簡單的方式,下面我們模擬一下

proca:

begin try

begin tran tran_proca

--proca的業務

exec procb

commit tran tran_procb

end try

begin catch

rallback tran tran_proca

end catch

procb:

declare @trancount int

set @trancount = @@trancount

begin try

if @trancount = 0

begin tran tran_procb;

--proca的業務

if @trancount = 0

commit tran tran_procb;

end try

begin catch

if @trancount = 0 

rollback tran tran_procb;

end catch

為了區分a和b,所以單獨對procb增加了對事務的判斷,原理很簡單,就是我再執行procb的時候,判斷事務有沒有開啟,當單獨呼叫procb的時候,@@trancount = 0,所以就會開啟事務。

但是如果在proca中呼叫procb的時候,事務已經開啟的,所以procb就不會再開啟事務了,如果有另外的儲存過程再呼叫proca,那麼也需要在proca中增加對@@trancount的判斷,主要要先賦值,且再進入事務之前就建立變更接收@@trancount的值,因為後面@@trancount會隨著事務的進行發生變化。

當然,這種方法也是有弊端的,因為對於複雜的業務來說,我們在對資料提交前會做很多的校驗,例如我裝箱之前要判斷是否有庫存,是否已經被裝箱,箱號是否重複等等資訊,再加上揀貨/反揀等等的狀態控制。其實我們會對很多表去關聯查詢來檢驗這個資料是否合法,顯然 這些都不適合放在事務內去操作,放在事務外我們使用with(nolock)關聯查詢,可以極大避免事務提交慢而鎖住一堆業務表,最終導致業務癱瘓。所以我們也要遵循乙個原則,事務內只處理增刪改,無關的表最好連查詢都不要放進去。

現在寫了不少mes業務的儲存過程之後再回想這些,其實我們都沒必要弄這麼複雜。儲存過程裡調儲存過程本身就不是乙個好的選擇,還是要推薦根據具體業務分析出合理的優化方式

Mysql 外來鍵與事務

a.什麼是外來鍵 外來鍵約束是指有關聯的兩個資料表之間的跨表條件約束。b.為什麼使用外來鍵 1.保證主表和從表資料的合理性。2.防止誤刪主表資料。3.限制不合理資料插入從表。a.外來鍵新增 語法 alter table 從表 add constraint 約束名字 foreign key 外來鍵字段...

Oracle與SQL Server事務處理的比較

事務處理是所有大型資料庫產品的乙個關鍵疑問,各資料庫廠商都在這個方面花費了很大精力,不同的事務處理方式會導致資料庫效能和功能上的巨大差異。事務處理也是資料庫管理員與資料庫運用 程式開發人員必須深刻理解的乙個疑問,對這個疑問的疏忽可能會導致運用 程式邏輯不正確以及效率低下。下面我們針對oracle及s...

SQL Server 2005事務隔離級別與效能

眾所周知,sql server事務隔離級別是為了保證在併發事務處理環境下的資料完整性,準確性,一致性的一種機制。在sql server2005中一共有五種事務隔離級別,分別為 read uncommitted,read committed,repeatable read,snapshot,seria...