在我們日常資料庫開發過程中,涉及到資料增刪改,無一例外都需要使用事務來控制其一致性。
而對於業務邏輯比較複雜的erp/mes/wms等系統來說,一致性尤其重要。
此時我們考慮乙個問題,儲存過程a開啟了事務,此時b由於業務需要呼叫儲存過程a,但是b又有自己的業務,也需要開啟事務。此時我們就需要考慮事務的一致。
而受sqlserver的事務機制影響,在第一次commit之後,事務計數就會重新,等到我們commit第二個事務的時候就會報錯:execute
後的事務計數指示
begin
和
commit
語句的數目不匹配。上一計數 = 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...