国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

.NET Remoting 實現分布式數據庫查詢

2024-07-10 12:58:46
字體:
來源:轉載
供稿:網友
前段時間,高級數據庫原理課程結課,老師布置了一個大作業——實現一個分布式數據庫查詢系統,因為鄙人一直學習.net,故想使用這個平臺實現,以進一步提高自身的水平。開始熱情致高,吾在網上搜了n天,也沒有什么好的資料,只找到一篇題目為《利用c#實現分布式數據庫查詢》的文章,此篇文章在多個site上都有雷同,作者不詳……
      摸索了幾天,找到了實現的方案——.net remoting 技術可以實現遠程對象,而ado.net則提供了強大的數據存取接口。我對ado.net比較熟悉,問題的難點就在與如何實現遠程服務器。雖然是一邊摸索,一邊做,但是已經小有成果,呵呵,基本實現了老師的要求,誠然,做出的這個東東還很幼稚,幾乎沒什么實際價值,但是,還是值得拿出來給有這方面需要的同行提供一些信息,或者請這方面的高手指點一下。
    下面開始言歸正傳。
     開始動手之前,你需要了解.net remoting 技術的基本理論,熟悉分布式數據庫原理,熟練掌握ado.net,并熟悉vs.net的開發環境。下面僅就這幾個方面做些簡單的介紹。
    remoting:一種分布式處理方式,也可將它看作是dcom的一種升級,它改善了很多功能,并極好的融合到.net平臺下。.net remoting 提供了一種允許對象通過應用程序域與另一對象進行交互的框架。
    在remoting中是通過通道(channel)來實現兩個應用程序域之間對象的通信的。

首先,客戶端通過remoting,訪問通道以獲得服務端對象,再通過代理解析為客戶端對象。這就提供一種可能性,即以服務的方式來發布服務器對象。遠程對象代碼可以運行在服務器上(如服務器激活的對象和客戶端激活的對象),然后客戶端再通過remoting連接服務器,獲得該服務對象并通過序列化在客戶端運行。
    在remoting中,對于要傳遞的對象,設計者除了需要了解通道的類型和端口號之外,無需再了解數據包的格式。但必須注意的是,客戶端在獲取服務器端對象時,并不是獲得實際的服務端對象,而是獲得它的引用。這既保證了客戶端和服務器端有關對象的松散耦合,同時也優化了通信的性能。
分布式數據庫系統
     就其本質而言,分布式數據庫系統的數據在邏輯上是統一的,而在物理上卻是分散的。與集中式數據庫相比它有如下主要優點:
  · 解決組織機構分散而數據需要相互聯系的問題。
  · 均衡負載。負載在各處理機間分擔,可避免臨界瓶頸。

· 可靠性高。數據分布在不同場地,且存有多個副本,即使個別場地發生故障,不致引起整個系統的癱瘓。
  · 可擴充性好。當需要增加新的相對自主的組織單位時,可在對當前機構影響最小的情況下進行擴充。
     ado.net
  分布式數據庫系統雖然有諸多優點,但它同時也帶來了許多新問題。如:數據一致性問題、數據遠程傳遞的實現、通信開銷的降低等,這使得分布式數據庫系統的開發變得較為復雜。幸運的是,微軟的.net開發環境為我們提供了c#開發語言和ado.net數據訪問模型,結合兩者來開發分布式數據庫系統能夠大大簡化開發工作。
    ado.net以xml為核心,是.net數據庫應用程序的解決方案。它使用離線數據結構,數據源中的數據被緩存到數據集(dataset)對象中,用戶無須鎖定數據源,數據以xml格式保存。在分布式數據庫系統中,很可能出現多個用戶同時訪問和修改數據的情況,因此,對于分布式數據庫系統,數據一致性是不可或缺的。ado.net通過使用樂觀一致性方案來控制數據一致性(實際上dataset對象被設計成支持使用樂觀一致性控制機制),即數據行只有在數據庫中真正被更新時才會被鎖定,而在悲觀一致性方案中,數據行在從被提取出來到在數據庫中更
新這段時間內一直被鎖定。因此,使用ado.net能夠在更少的時間內響應數量巨大的用戶。
  另外,在分布式數據庫系統中,還會經常遇到當用戶修改自從提取出來以來已經被修改的行時,違反一致性原則。對此問題ado.net也作了很好地解決,即使用dataset對象為每一條修改過的記錄維護兩個版本:原始版本和更新版本,在更新的記錄被寫回數據庫之前,先要把數據集中記錄的原始版本與數據庫中的當前版本進行比較,如果兩個版本匹配,就在數據庫中更新記錄;否則,就會出現違反一致性原則的錯誤。
    下面開始程序實現。


第1章 系統總體結構

1.1 總體結構圖 系統實現需要部署服務器端的遠程對象(即一個dbserverlibrary.dll),服務器端要注冊通道和該遠程對象。客戶端要實現一個本地查詢的服務器,同時根據sql解析的結果向各個服務器發送命令,并將結果顯示在客戶端界面,服務器端可以接受并顯示相應的命令。

1.2 關鍵組件結構圖

系統結構中關鍵的組件有遠程對象,和本地服務器,實現的功能基本一致。下面以遠程

對象為例,說明組件的實現。遠程對象在服務器端解決方案下的庫文件中聲明,通過服務器端進行注冊,客戶端通過tcp通道與服務器端遠程對象通信,實現數據集的查詢和傳輸。主要的數據成員有:sqlconnection(sql server數據庫的連接對象)、 sqlcommand (sql命令對象)、sqldataadapter(數據適配器,填充數據集)組件——dbserverlibrary:

 

第2 章 數據字典結構

       因時間倉促,未實現數據字典,所有實驗要求的sql經過解析后,直接通過代碼判斷,

向相應場地發送命令。

第3 章 代碼結構

代碼分為三部分:遠程對象,服務器端代碼和客戶端代碼。

其中:遠程對象部署在各個服務器端,客戶端除了實現查詢命令的解析和傳送外

外,還有一個本地服務器,進行相應的本地查詢。

遠程對象代碼:

using system;

using system.runtime.serialization;

using system.data;

using system.data.sqlclient;

using system.windows.forms;

namespace dbserverlibrary

{

              [serializableattribute]    //it is very important for remoting data

       public class dbserver : marshalbyrefobject

       {

              private string connstr;

              private string clientsql;

 

              public sqlconnection sqlconn;

              public sqlcommand sqlcomm;

              public sqldataadapter sqladapter;

 

 

              public void getclientsql(string sql)

              {

                     if(clientsql != null)

                     {

                            clientsql = null;

                     }

                     clientsql = sql;

                     messagebox.show(clientsql);

              }

 

              public dbserver()

              {

                     //localdata initialize

                     connstr = "data source = localhost;initial catalog=ddb;user id=sa;password=;";

                     sqlconn = new sqlconnection(connstr);

              }

             

              public dataset getdataset()  // 執行select

              {

                     dataset ds = new dataset();

                     if (sqlcomm != null)

                     {

                            sqlcomm = null;

                     }

                     if(sqlconn.state == connectionstate.closed)

                     {

                            sqlconn.open();

                     }

                     try

                     {

                            sqlcomm = new sqlcommand();

                            sqlcomm.connection = sqlconn;

                            sqlcomm.commandtext = clientsql;

                            sqlcomm.commandtype = commandtype.text;

                           

                            sqladapter = new sqldataadapter();

                            sqladapter.selectcommand = sqlcomm;

                            sqladapter.fill(ds);

                     }

                     catch(sqlexception ex)

                     {

                            messagebox.show(ex.message);

                     }                  

                     return ds;

              }

 

              public int executesql()   //執行insert和delete

              {

                     int affectednumber;

                     if (sqlcomm != null)

                     {

                            sqlcomm = null;

                     }

                     if(sqlconn.state == connectionstate.closed)

                     {

                            sqlconn.open();

                     }

                     try

                     {

                            sqlcomm = new sqlcommand();

                            sqlcomm.connection = sqlconn;

                            sqlcomm.commandtype = commandtype.text;

                            sqlcomm.commandtext = clientsql;

                            affectednumber = sqlcomm.executenonquery();

                            return affectednumber;       

                     }

                     catch(sqlexception ex)

                     {

                            messagebox.show(ex.message);

                            return 0;

                     }

              }

       }

}

 

服務器端代碼:

private void frmsupplierserver_load(object sender, system.eventargs e)

              {

                     tcpchannel chan = new tcpchannel(8888);

                     channelservices.registerchannel(chan);

                     //注冊提供服務的遠程對象         remotingconfiguration.registerwellknownservicetype(typeof(dbserverlibrary.dbserver)                ,"dbserver",wellknownobjectmode.singleton);

              }

客戶端代碼:

解析sql:sqlparse.cs

namespace supplierclient

{

       public class sqlparse

       {

              //得到sql語句的類型

              public string getsqltype(string sqltext)  //type of sql statements

              {

                    

              }

              //得到select語句要查詢的表名

              public string getselecttablename(string sqltext)

              {

                    

              }

              //得到select語句中的where子句

              public string getwhereclause(string sqltext)

              {

                    

              }

              //得到查詢條件中的字段名

              public string getselectfield(string sqltext)

              {

                    

              }

              //得到分片依據,返回scity的值

              public string getselectcityvalue(string sqltext)

              {

                    

              }

              //設定select語句經解析后的格式

              public arraylist setselectlist(string sqltext)

              {           

              }

              //如果沒有分片信息,則向3個場地都發送命令

              public arraylist sendtoallsite(string sqltext)

              {                  

              }

              //得到insert語句要查詢的表名

              public string getinserttablename(string sqltext)

              {

                    

              }

 

              //根據插入的表和值,設定場地:insert into supplier values('no','name','city'),return city

              public string getinsertcityvalue(string sqltext)

              {

                    

              }

 

              //如果表名是supplier,則根據city值設定向哪個場地發送命令

              public arraylist setinsertsite(string sqltext)

              {

                    

         }

              //生成解析后的insert命令列表

              public arraylist setinsertlist(string sqltext)

              {

 

              }

 

本地服務器查詢代碼:localserver.cs

namespace supplierclient

{

       public class localserver

       {

 

       }

 

              //返回查詢結果

              public dataset makedataset(string sqltext)

              {

                    

              }

 

              //執行插入和刪除操作,并返回影響記錄數

              public int executesql(string sqltext)

              {

 

              }

 

 

 

第4 章 界面

4.1 客戶端     

客戶端啟動后,用戶首先在文本框中輸入sql命令,然后通過解析后向相應場地發送命令,并將返回的結果集進行合并,顯示在界面中,顯示結果后空白的文本框用來顯示執行插入刪除操作時的結果信息。

4.2 服務器

服務器端僅實現對遠程對象的注冊,因此界面不需要實現功能,只需要在啟動時注冊遠程對象即可,接收到的客戶端的用戶命令是通過消息框顯示的。如上圖所示。

 

 

第5 章 命令處理及核心算法流程

insert 操作——

       //得到insert語句要查詢的表名

              public string getinserttablename(string sqltext)

              {

                    

              }

 

//根據插入的表和值,設定場地:insert into supplier values('no','name','city'),return city

              public string getinsertcityvalue(string sqltext)

              {

                    

              }

 

              //如果表名是supplier,則根據city值設定向哪個場地發送命令

              public arraylist setinsertsite(string sqltext)

              {

 

             }

 

              //生成解析后的insert命令列表

              public arraylist setinsertlist(string sqltext)

              {

              }

delete 操作——

向各個場地發送,通過定義數據庫中表的關系及約束來保證完整性和一致性,如果刪除命令不成功,則返回異常信息,否則,返回各個場地成功執行命令影響的記錄數目。

select 操作——

              //得到sql語句的類型

              public string getsqltype(string sqltext)  //type of sql statements

              {

                    

              }

 

              //得到select語句要查詢的表名

              public string getselecttablename(string sqltext)

              {

                    

              }

 

              //得到select語句中的where子句

              public string getwhereclause(string sqltext)

              {

              }

              //得到查詢條件中的字段名

              public string getselectfield(string sqltext)

              {

                    

              }

 

              //得到分片依據,返回scity的值

              public string getselectcityvalue(string sqltext)

              {

                    

              }

 

              //設定select語句經解析后的格式

              public arraylist setselectlist(string sqltext)

              {

                    

              }

              //如果沒有分片信息,則向3個場地都發送命令

              public arraylist sendtoallsite(string sqltext)

              {

                    

              }

第6章 結論

遠程處理是.net框架提供的一項強大的技術,利用它可以使位于任何位置的應用程序互相通信,這些應用程序可能在同一臺計算機上運行,也可能位于同一局域網中的不同計算機上,或者位于相隔萬里的有巨大差異的網絡中。

使用.net remoting技術結合ado.net能夠高效、可靠地解決這兩方面的問題。具體表現為,在c#中通過使用.net遠程處理框架能夠方便地解決數據、命令遠程傳遞問題;c#通過ado.net對數據庫進行操作,使分布式數據庫系統中對數據庫的各種操作變得高效、可靠,同時易于解決數據一致性問題。

由于時間關系,程序中仍有部分bug,將在下一步繼續完善,而且,還應進一步完善數據字典,使程序結構更加清晰,增強可擴充性。

收集最實用的網頁特效代碼!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 江口县| 晋宁县| 逊克县| 华宁县| 晋州市| 鄂尔多斯市| 海淀区| 桐城市| 襄汾县| 勃利县| 象州县| 台东市| 沐川县| 长岛县| 东光县| 漯河市| 南华县| 瓮安县| 稷山县| 阳东县| 炎陵县| 桂林市| 珠海市| 淮滨县| 内江市| 涿鹿县| 沙河市| 师宗县| 寿光市| 阜宁县| 栖霞市| 泗水县| 紫云| 扶余县| 恩平市| 垣曲县| 成安县| 扶绥县| 大渡口区| 独山县| 志丹县|