知方可补不足~Sqlserver发布订阅与sql事务的关系
前几讲说了一下通过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条数据的任何一条进行修改,那只能等待事务结束后了......
分类:
数据库
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
2013-01-16 Jquery真的不难~第四回 JQ也是事件驱动的(匿名函数的使用)
2013-01-16 将不确定变为确定~transactionscope何时提升为分布式事务~续
2013-01-16 Jquery真的不难~第三回 如何改变HTML标签的样式
2013-01-16 Castle~动态代理实现对方法的拦截
2012-01-16 谁说LINQ复杂查询不支持返回实名类型~复杂结果集中再使用复杂结果集