前幾講說了一下通過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條數據的任何一條進行修改,那只能等待事務結束后了......
文章列表