开始动手之前你需要了解NET Remoting 技术的基本理论熟悉分布式数据库原理熟练掌握ADONET并熟悉VSNET的开发环境下面仅就这几个方面做些简单的介绍
Remoting一种分布式处理方式也可将它看作是DCOM的一种升级它改善了很多功能并极好的融合到Net平台下NET Remoting 提供了一种允许对象通过应用程序域与另一对象进行交互的框架
在Remoting中是通过通道(channel)来实现两个应用程序域之间对象的通信的
首先客户端通过Remoting访问通道以获得服务端对象再通过代理解析为客户端对象这就提供一种可能性即以服务的方式来发布服务器对象远程对象代码可以运行在服务器上(如服务器激活的对象和客户端激活的对象)然后客户端再通过Remoting连接服务器获得该服务对象并通过序列化在客户端运行
在Remoting中对于要传递的对象设计者除了需要了解通道的类型和端口号之外无需再了解数据包的格式但必须注意的是客户端在获取服务器端对象时并不是获得实际的服务端对象而是获得它的引用这既保证了客户端和服务器端有关对象的松散耦合同时也优化了通信的性能
分布式数据库系统
就其本质而言分布式数据库系统的数据在逻辑上是统一的而在物理上却是分散的与集中式数据库相比它有如下主要优点
· 解决组织机构分散而数据需要相互联系的问题
· 均衡负载负载在各处理机间分担可避免临界瓶颈
· 可靠性高数据分布在不同场地且存有多个副本即使个别场地发生故障不致引起整个系统的瘫痪
· 可扩充性好当需要增加新的相对自主的组织单位时可在对当前机构影响最小的情况下进行扩充
ADONET
分布式数据库系统虽然有诸多优点但它同时也带来了许多新问题如数据一致性问题数据远程传递的实现通信开销的降低等这使得分布式数据库系统的开发变得较为复杂幸运的是微软的NET开发环境为我们提供了C#开发语言和ADONET数据访问模型结合两者来开发分布式数据库系统能够大大简化开发工作
ADONET以XML为核心是Net数据库应用程序的解决方案它使用离线数据结构数据源中的数据被缓存到数据集(DataSet)对象中用户无须锁定数据源数据以XML格式保存在分布式数据库系统中很可能出现多个用户同时访问和修改数据的情况因此对于分布式数据库系统数据一致性是不可或缺的ADONET通过使用乐观一致性方案来控制数据一致性(实际上DataSet对象被设计成支持使用乐观一致性控制机制)即数据行只有在数据库中真正被更新时才会被锁定而在悲观一致性方案中数据行在从被提取出来到在数据库中更
新这段时间内一直被锁定因此使用ADONET能够在更少的时间内响应数量巨大的用户
另外在分布式数据库系统中还会经常遇到当用户修改自从提取出来以来已经被修改的行时违反一致性原则对此问题ADONET也作了很好地解决即使用DataSet对象为每一条修改过的记录维护两个版本原始版本和更新版本在更新的记录被写回数据库之前先要把数据集中记录的原始版本与数据库中的当前版本进行比较如果两个版本匹配就在数据库中更新记录否则就会出现违反一致性原则的错误
下面开始程序实现
第章 系统总体结构
总体结构图
系统实现需要部署服务器端的远程对象(即一个DbServerLibrarydll)服务器端要注册通道和该远程对象客户端要实现一个本地查询的服务器同时根据SQL解析的结果向各个服务器发送命令并将结果显示在客户端界面服务器端可以接受并显示相应的命令
关键组件结构图
系统结构中关键的组件有远程对象和本地服务器实现的功能基本一致下面以远程对象为例说明组件的实现远程对象在服务器端解决方案下的库文件中声明通过服务器端进行注册客户端通过TCP通道与服务器端远程对象通信实现数据集的查询和传输主要的数据成员有SqlConnection(SQL Server数据库的连接对象) SqlCommand (SQL命令对象)SqlDataAdapter(数据适配器填充数据集)组件——DbServerLibrary:
第 章 数据字典结构
因时间仓促未实现数据字典所有实验要求的SQL经过解析后直接通过代码判断向相应场地发送命令
第 章 代码结构
代码分为三部分远程对象服务器端代码和客户端代码
其中远程对象部署在各个服务器端客户端除了实现查询命令的解析和传送外外还有一个本地服务器进行相应的本地查询
远程对象代码
using System;
using SystemRuntimeSerialization;
using SystemData;
using SystemDataSqlClient;
using SystemWindowsForms;
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;
MessageBoxShow(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(sqlConnState == ConnectionStateClosed)
{
sqlConnOpen();
}
try
{
sqlComm = new SqlCommand();
sqlCommConnection = sqlConn;
sqlCommCommandText = clientSql;
sqlCommCommandType = CommandTypeText;
sqlAdapter = new SqlDataAdapter();
sqlAdapterSelectCommand = sqlComm;
sqlAdapterFill(ds);
}
catch(SqlException ex)
{
MessageBoxShow(exMessage);
}
return ds;
}
public int ExecuteSql() //执行insert和delete
{
int affectedNumber;
if (sqlComm != null)
{
sqlComm = null;
}
if(sqlConnState == ConnectionStateClosed)
{
sqlConnOpen();
}
try
{
sqlComm = new SqlCommand();
sqlCommConnection = sqlConn;
sqlCommCommandType = CommandTypeText;
sqlCommCommandText = clientSql;
affectedNumber = sqlCommExecuteNonQuery();
return affectedNumber;
}
catch(SqlException ex)
{
MessageBoxShow(exMessage);
return ;
}
}
}
}
服务器端代码
private void frmSupplierServer_Load(object sender SystemEventArgs e)
{
TcpChannel chan = new TcpChannel();
ChannelServicesRegisterChannel(chan);
//注册提供服务的远程对象 RemotingConfigurationRegisterWellKnownServiceType(typeof(DbServerLibraryDbServer)DbServerWellKnownObjectModeSingleton);
}
客户端代码
解析SQLSqlParsecs
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)
{