SQL Server数据库数据与内存中存储数据的同步问题


这段时间在重新实现DataCenter与数据库数据的更新的模块,由于使用的数据库为SQL Server,所以就查阅了一些数据库本身对更新的支持,下面就说说整个查找过程吧。

CDC及Change Tracing

由于使用的sql server为2008版,所以就首先去了解了CDC(Change Data Capture)这个功能,它能通过对日志文件的读取获得数据表经过了哪些数据更新(DML及DDL)操作,并且记录更新操作是一个异步的过程,关于如何使用及一些注意事项网上资源也挺多的,不过还是要提醒一点,在启用的时候千万别忘记启动数据库代理功能,不然CDC就无法工作。Change Tracing和CDC差不多,可以当作一个轻量版本的CDC吧,但是他是同步的,在一个事务中完成,所以在这里也被PASS了。

Service Broker

当时在stackoverflow上也咨询过这方面的问题,当时是看到它有一个队列,可以将更改信息发送到队列保存,使得应用程序能够通过队列获取到数据表的数据更新信息,从而只需要监听这个队列就能及时的获取变更数据,不过这种发送数据到队列的操作是需要由数据库在一个触发器中主动执行SEND操作,但是在我们当前的环境中是不允许使用触发器,所以作罢。后来看到stackoverflow上的一个老哥介绍说试试QueryNotification,并且还很热情的给出了一部分使用代码,在查询了这个功能及与他做了一些沟通之后,因为它会一直占用一个数据库连接并且不能给出相对有用的更新信息及业务上的一些其它原因,PASS。

CLR集成

其实在当时在测试Service Broker的时候,是想利用CDC+Service Broker来完成这个数据的功能,但是上面也说了由于Service Broker会一直占用一个连接,所以就没使用,后来是想着使用CLR集成做一个存储过程,将这个存储过程放到一个数据库JOB中,JOB完成轮询CDC表的过程,当发现有数据更新时就执行存储过程,而这个存储过程就完成一个功能,将CDC表中的数据发送到外界的应用程序。个人感觉CLR集成是SQL Server中比较好的一个功能,能让数据库调用C#编写的类库,极大的方便了存储过程功能的实现。这里要注意一个问题,就是因为要通过网络把数据从数据库中发送出来,所以在创建程序集的时候需要开启UNSAFE权限。

例如:CREATE ASSEMBLY TcpClr FROM 'G:\TcpClrTest.dll' WITH PERMISSION_SET = UNSAFE

当然有时候执行这条语句的时候会失败,给出的出错信息也比较详细,根据出错信息修改问题应该不大,大概就是说不是数据库所有者(DBO)及需要什么证书之类的。在查阅了MSDN之后,解决方法也比较容易

ALTER DATABASE DBNAME SET TRUSTWORTHY ON

上面这条语句相对比较简单,还有一种方法就是创建非对称证书,具体可以查询MSDN,根据自己的业务环境选择一个方法。

GRANT EXTERNAL ACCESS ASSEMBLY TO LOGINNAME

目前的一个方案是:有一个服务端在ACCEPT,等待数据库端连接;数据库端有一个作业每隔一段时间都会轮询一遍所有CDC的表,若发现有数据更新,则连接服务端,将更新数据及相关的操作信息发送给服务端,服务端根据这些信息做出数据的更新。

当然这个只是一个初步的想法,在逻辑上是可行的,具体还是要和业务相结合并做出相应的修改。以上说的比较简单与笼统,其中还有很多细节需要注意,相应的知识点也可以很方便的在google搜寻到,还有就是千万别忽略了stackoverflow,在上面查询你的问题,大部分都是能直接检索出你想要的答案,若没有,也可以发起一个提问,过不了多久就会有人帮你解答。


非专业娱乐型程序员。
Published under (CC) BY-NC-SA in categories 技术  tagged with C#  SQL Server