• SqlDependency缓存用法


    系列目录:

    SqlDependency缓存用法

    Asp.net使用SqlDependency

    SqlCacheDependency使用命令通知使缓存无效

    CacheDependency用法

    AggregateCacheDependency 用法

    SqlCacheDependency使用轮流检测技术(轮询)使缓存无效

    ----------------------------------------------------------------------------------------------

        在Microsoft SQL Server数据库中的数据发生变化时,SqlDependency类能够提供一种方法,将这种变化通知应用程序。可以使用这种通知来终止缓存和重新加载数据库服务器中的数据。
        通知是一项耗资源的任务,应选择变更频率较小的数据。
        对于使用少数客户(Web服务器或组件服务器)同时为成百上千名用户提供服务的Web应用程序或中间层组件,最好使用SqlDependency类。因此,可以缓存大型表,但是在应用程序收到一个修改通知时,通过终止缓存以错开重新加载这些表的时机,只有在用户再次引用数据时,才会重新加载缓存。

        SqlDependency是.net2.0封装的一个类型,在sql2005及以上版本才能使用。

    使用方法:

    1、必须在 MSDB 数据库中的 QueryNotificationService 服务上向Guest用户授予发送权限。方法如下,注意要区分大小写。 (我在做实时证并没有操作此步也可以运行,可能是以前就有此功能了吧)

    USE MSDB
    GRANT SEND ON SERVICE::
    [http://schemas.microsoft.com/SQL/Notifications/QueryNotificationService]
    TO GUEST

    2、启用CLR
    在一个消息到达服务队列时,一个包含.Net代码的存储过程sp_DispatcherProc将使用一个队列来派发消息。因此必须启用Sql Server中的CLR功能。启用方法如下:

    Use Master
    Exec sp_configure 'clr enabled',1
    Reconfigure
    3、SqlDependency 对象会使用 Service Broker 将消息发送给 QueryNotificationService服务,所以需要启用 Service Broker。可以通过下边语句查看是否启用。
    select DatabasePropertyex('Northwind','IsBrokerEnabled')
    --返回1表示true,返加0表示false

        启动Service Broker语句如下:

    use master
    Alter Database Northwind set enable_broker

    4、使用SqlDependency。

    建立一个WinFrom项目,窗口名称为FormDependency,在窗口上放一个DataGridView。编写下边代码。

    using System.Data.SqlClient;
    using System.Configuration;

    namespace SqlDependencyUse
    {
        
    public partial class FormDependency : Form
        {
            
    private static string connectString = ConfigurationManager.ConnectionStrings["NHibernateSampleDb"].ToString();

            
    private delegate void GridDelegate(DataTable table);
            
    private SqlDependency dep;
            
    public FormDependency()
            {
                InitializeComponent();
            }

            
    private void FormDependency_Load(object sender, EventArgs e)
            {
                
    //启动一个与Sql Server进行通信的客户端进程
                SqlDependency.Start(connectString);
                UpdateGrid();
            }



            
    private void FormDependency_FormClosed(object sender, FormClosedEventArgs e)
            {
                
    //终止与Sql Server通信
                SqlDependency.Stop(connectString);
            }

            
    private void UpdateGrid()
            {
                
    string sql = "select [CustomerId],[Firstname],[Lastname],[Version] from [dbo].[Customer]";
                DataTable dt 
    = new DataTable();
                
    using (SqlConnection cn = new SqlConnection(connectString))
                {
                    
    using (SqlCommand cmd = new SqlCommand(sql, cn))
                    {
                        cn.Open();
                        
    //SqlCommand对象包含一个Notification属性,可以将SqlCommand对象传递给SqlDependency对象的构造函数,以设置该属性。
                        dep = new SqlDependency(cmd);
                        
    //当有DML操作时,onChange事件会接收来自Sql Server通过sq_DispatcherProc存储过程发送给应用程序的消息。
                        dep.OnChange += new OnChangeEventHandler(dep_OnChange);
                        
    using (SqlDataReader rdr = cmd.ExecuteReader())
                        {
                            dt.Load(rdr);
                        }
                    }
                }
                dgvView.Invoke(
    new GridDelegate(dgvDelegateMethod), dt);
            }
            
    private void dgvDelegateMethod(DataTable dtVal)
            {
                dgvView.DataSource 
    = dtVal;
            }

            
    /// <summary>
            
    /// SqlDependency的onChange事件处理
            
    /// </summary>
            
    /// <param name="sender"></param>
            
    /// <param name="e"></param>
            void dep_OnChange(object sender, SqlNotificationEventArgs e)
            {
                System.Diagnostics.Debug.WriteLine(
    "接收到事件");

                
    if (e.Info == SqlNotificationInfo.Invalid)
                {
                    MessageBox.Show(
    "Invalid Statement");
                    
    return;
                }
                UpdateGrid();
            }

        }
    }

        注: 上边代码中的查询语句写法要非常严格。必须按SQL Server Service Broker提供制定规则的查询语句,一般来讲,必须是简单的sql查询语句(不能用*,不能用top,不能用函数,包括聚合函数,不能用子查询,包括where后的子查询,不能用外连接,自连接,不能用临时表,不能用变量,不能用视图,不能垮库,表名之前必须加类似dbo数据库所有者这样的前缀)例如:select * from table1,select column1 from table1,select count(*) from table1 都是错误的sql查询语句,select column1 from dbo.table1 则是正确的语句。

         我刚刚测试时,发现始终无法触发onChange事件,让我郁闷了好长时间,后来发现SQL中没有加[dbo]。

     5、测试,打开SqlServer,修改其中的数据。界面上DataGridView的数据也会一起更新。

  • 相关阅读:
    Java(2)数据类型与变量
    Java(6)控制流程
    Java(7)大数
    Java(1)初识Java程序
    Java(4)字符串
    Java(3)运算符
    Java(5)输入与输出
    一篇文章轻松学会python装饰器
    Python学习:数据类型转换的方法教程
    python面向对象教程:类和实例
  • 原文地址:https://www.cnblogs.com/scottckt/p/1964923.html
Copyright © 2020-2023  润新知