文章出處

回到目錄

前幾講說了一下通過sqlserver的發布與訂閱來實現數據的同步,再通過EF這個ORM架構最終實現架構系統的讀寫分離,而在使用發布與訂閱來實現數據同步時,需要我們注意幾點,那就是當操作被使用在“事務上下文”時,你的同步操作有可能會被延時,嘟嘟!

這個不難理解,我們都知道事務有一些級別,而最高級別serializable 又是.net TransactionScope默認的級別,所以,在程序開發中,只要用了事務,基本都是serializable,而這個級別是最安全的,當然對于SQL來說,也是最容易發生死鎖及阻塞的,呵呵。

如果對要SQL鎖不清楚的同學,可以看我的這篇文章《知方可補不足~Sqlserver中的幾把鎖和.net中的事務級別

下面是我總結的,在事務為serializable級別,對于發布訂訂閱同步的關系

set transaction isolation level serializable 
begin tran
 
select * from User_Info                --讀取所有數據,等待事務結束后才能同步 TAB(S) ,TAB(IX)    
update User_Info set Status=1 where UserInfoID=1 --更新其他數據,可以立即同步  TAB(IX),Page(IX),Key(X)
select * from User_Info where UserInfoID=1       --事務中讀取其他數據,可以立即同步 TAB(IS),KEY(S),Page(IS)
select * from User_Info where UserInfoID=28      --事務中讀當前數據,等待事務結束后才能同步   TAB(IS),KEY(S),Page(IS)
select * from User_Info where UserInfoID<30      --事務中讀取范圍數據,包括要同步的數據,等待事務結束后才能同步,tab(is), KEY(ranges-s),page(is)
select * from User_Info where UserInfoID<10      --事務中讀取范圍數據,不包括要同步的數據,可以立即同步,tab(is), KEY(ranges-s),page(is)

waitfor delay '00:02:00' --等待2分鐘 
commit tran

通過上面的結果,我們可以知道,只要當前需要同步(正在發生變化的數據,就是要同步的數據)的數據不在被鎖的范圍里,就不會對同步有所影響,當然,你要是在事務里來個select * from table,那你就玩完了,需要等待你的事務結束后,你這個張表發生變

化的數據才能被同步,所以,經驗告訴我們,在事務里,能不寫查詢就不要寫,呵呵。

下面圖中顯示的是在一個事務里添加了范圍鎖的例子,看上支挺恐怖的,它對應的語句是select * from User_Info where UserInfoID<10,直接查詢出10條數據,這時,SQL會把這10條數據分別加上范圍共享鎖,以對這10條數據進行保護,你此時,要想對這10條數據的任何一條進行修改,那只能等待事務結束后了......

回到目錄


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣()