初试Sql Server 2005 查询通知

        “查询通知”可能是我们处理那些不经常变化的缓存数据的一种解决方案了,数据库中的对应表字段的更新会立刻通知.Net应用程序,我们可以在这时修改缓存的数据,使数据一直保持最新。例如:系统中的系统参数等设置可以在系统加载时设置缓存并设置查询通知,如果数据更新了,就立刻更新缓存即可。
        参考一些文章,剖析SQL Server 2005查询通知之基础篇,自己也来简单实践一下:

1.
执行sql,让测试数据库SqlNotificationDb支持查询通知

USE master
ALTER DATABASE sqlnotificationdb SET ENABLE_BROKER
2.建立一个WinForm程序,窗体上添加一个DataGridView控件,显示数据使用。
3.设置SqlDependency.Start(),SqlDependency.Stop();一般在应用程序开始和结尾。
SqlDependency.Start()
        static string conStr = ConfigurationManager.ConnectionStrings["SqlNotificationDb"].ConnectionString;
        
private void Form1_Load(object sender, EventArgs e)
        
{
            SqlDependency.Start(conStr);
            
this.BindAsyn(BindData);
        }
SqlDependency.Stop()
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        
{
            SqlDependency.Stop(conStr);
        }

4.从数据库中取数据,并设置查询通知
        //绑定数据的方法,一直在主线程中调用
        private void BindData()
        
{
            SqlConnection con 
= new SqlConnection(conStr);
            SqlCommand cmd 
= new SqlCommand("select fid,fcode,fname from dbo.table1", con);
            
//每次重新刷新完数据后,需要重新设置SqlDependency
            SqlDependency dep = new SqlDependency(cmd);
            dep.OnChange 
+= new OnChangeEventHandler(dep_OnChange);
            
//////////////////////////////////////////////////////////////////////////////////////
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            DataSet ds 
= new DataSet();
            da.Fill(ds);
            
this.dataGridView1.DataSource = ds.Tables[0];
        }

5.定义"查询通知"回调的方法dep_OnChange
        void dep_OnChange(object sender, SqlNotificationEventArgs e)
        
{
            
if (e.Info == SqlNotificationInfo.Insert ||
                e.Info 
== SqlNotificationInfo.Update ||
                e.Info 
== SqlNotificationInfo.Delete)
            
{
                
this.BindAsyn(BindData);
            }

        }
6.由于"查询通知"调用的方法onchange不在主线程里,不能直接操作由主线程创建的DataGridView,所以对Bind方法做一些处理,不是直接调用BindData()方法,而是调用BindAsyn方法。这个方法的作用是,在主线程中直接调用,不在主线程时调用this.Invoke(),还是让主线程调用BindData方法。
        private delegate void BindHandler();
        
private void BindAsyn(BindHandler myDelegate)
        
{
            
if (this.InvokeRequired)
            
{
                 
this.Invoke(myDelegate);
            }

            
else
            
{
                myDelegate();
            }

        }

7.测试,运行!窗体DataGridView得到表中所有记录。这时,打开Sql server management studio,修改表中记录,数据修改后,窗体直接进行刷新,将最新的数据取出。运行多个窗体,可以看见,一旦数据库程序一改,所有窗体都自动随之标化。(这时为了测试"查询通知"的功能,最好不要这样使用"查询通知"。)为什么?请大家注意下面的话:
 何时使用查询通知
  查询通知是针对于并不经常改变的数据而设计的。最好把它应用于服务器端的应用程序(例如ASP.NET或remoting)而不是客户端应用程序(例如Windows表单应用程序)。记住,每一个通知请求都要在SQL Server中注册。如果你拥有大量的都有通知请求的客户端应用程序,那么这可能会导致你的服务器产生资源问题。微软推荐,对于客户端应用程序,你应该限制查询通知使用为不多于十个并行用户。

  对于大规模应用程序来说,查询通知可能是一种强有力的帮助,而不用简单地添加越来越多的服务器以满足要求。设想,有一家大型的为成千上百万用户提供在线软件更新服务的软件公司。不是使每一个用户的更新操作都触发服务器上的另一个查询来确定需要哪些组件,而是能够缓冲查询结果并且可以直接从该缓存中服务匹配的查询。

  注意:对于客户端应用程序来说,应该限制你的查询通知使用—不多于十个并发用户。

  对于较小规模的情况而言,下拉式列表框是另一种典型的数据集;此时该数据集更新的次数并不如请求的次数多。产品列表、州列表、国家列表、供应商、销售人,甚至更多不太需要频繁改变的信息正是使用通知的较好候选。

8.源代码下载SqlNotificationTest.rar

posted on 2008-03-22 23:37  fredli2005  阅读(1102)  评论(3编辑  收藏  举报

导航