回到目录 前几讲说了一下通过sqlserver的发布与订阅来实现数据的同步,再通过ef这个orm架构最终实现架构系统的读写分离,而在使用发布与订阅来实现数据同步时,需要我们注意几点, 那就是当操作被使用在事务上下文时 ,你的同步操作有可能会被延时,嘟嘟!
回到目录
前几讲说了一下通过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 userinfoid30 --事务中读取范围数据,包括要同步的数据,等待事务结束后才能同步,tab(is), key(ranges-s),page(is)select * from user_info where userinfoid10 --事务中读取范围数据,不包括要同步的数据,可以立即同步,tab(is), key(ranges-s),page(is)waitfor delay '00:02:00' --等待2分钟 commit tran
通过上面的结果,我们可以知道,只要当前需要同步(正在发生变化的数据,就是要同步的数据)的数据不在被锁的范围里,就不会对同步有所影响,当然,你要是在事务里来个select * from table,那你就玩完了,需要等待你的事务结束后,你这个张表发生变
化的数据才能被同步,所以,经验告诉我们,在事务里,能不写查询就不要写,呵呵。
下面图中显示的是在一个事务里添加了范围锁的例子,看上支挺恐怖的,它对应的语句是select * from user_info where userinfoid10,直接查询出10条数据,这时,sql会把这10条数据分别加上范围共享锁,以对这10条数据进行保护,你此时,要想对这10条数据的任何一条进行修改,那只能等待事务结束后了......
回到目录