很久没有写DIOCP的Demo了,主要公司的事情太繁琐,工作之余都不想动了,之前承若的群里面朋友们的DEMO,昨天晚上恶补了一下,把对数据库连接池的操作加入到了Demo中,大家可以通过SVN下载到最新的代码和Demo。

好了我带大家看看这次的DEMO,经过群里面朋友们的推荐,这次代码中引用了UntCobblerUniPool连接池代码来完成的本次的DEMO,研究了下代码,里面使用的线程时钟来做死连和多余连接的释放。感谢UntCobblerUniPool作者无私奉献的精神。

先截个图,看看服务端的界面。

主要加入了多帐套的连接的配置。配置文件存放在config\dbpool.config,是一个json格式的文件配置

{
"account2013": {
  "connString": "Provider Name=SQL Server;Data Source=192.168.1.2;Database=xxxx;User ID=sa;Password=sa"
},
"account2012": {
  "connString": "Provider Name=SQL Server;Data Source=192.168.1.2;Database=xxx02;User ID=sa;Password=sa"
}
}

DEMO中我演示了两个帐套(实际运行中帐套个数是不固定),account2013和account2012代表帐套的ID,在clientContext中可以通过客户端传递过来的帐套ID,获取连接字符串,到连接池中获取一个连接。

看看服务端的代码

  1. procedure TClientContext.dataReceived(const pvDataObject:TObject);
  2. var
  3. lvJsonStream:TJSonStream;
  4. lvFile:String;
  5. lvCmdIndex:Cardinal;
  6. lvXMLData, lvEncodeData:AnsiString;
  7. lvSQL, lvID:String;
  8. lvDBDataOperator:TUniOperator;
  9. lvPoolObj:TUniCobbler;
  10.  
  11. begin
  12. lvJsonStream := TJSonStream(pvDataObject);
  13. try
  14. lvCmdIndex := lvJsonStream.JSon.I['cmdIndex'];
  15.  
  16. //执行SQL的命令ID
  17. if lvCmdIndex= then
  18. begin
  19. //客户端传递过来的帐套ID
  20. lvID := lvJsonStream.Json.S['config.accountID'];
  21. if lvID = '' then
  22. begin
  23. raise Exception.Create('没有指定帐套ID(config.accountID)');
  24. end;
  25.  
  26. //客户端指定要执行的SQL
  27. lvSQL := lvJsonStream.Json.S['script.sql'];
  28. if lvSQL = '' then
  29. begin
  30. raise Exception.Create('没有指定要执行的SQL!');
  31. end;
  32.  
  33. //通过帐套ID获取一个连接池对象
  34. lvPoolObj := TUniPool.getConnObject(lvID);
  35. try
  36. //打开连接
  37. lvPoolObj.checkConnect;
  38.  
  39. //Uni数据库操作对象<可以改用对象池效率更好>
  40. lvDBDataOperator := TUniOperator.Create;
  41. try
  42. //设置使用的连接池
  43. lvDBDataOperator.Connection := lvPoolObj.ConnObj;
  44. self.StateINfo := '借用了一个lvADOOpera,准备打开连接!';
  45. try
  46. //获取一个查询的数据
  47. lvXMLData := lvDBDataOperator.CDSProvider.QueryXMLData(lvSQL);
  48. self.StateINfo := 'lvADOOpera,执行SQL语句完成,准备回写数据';
  49. except
  50. raise;
  51. end;
  52.  
  53. lvJsonStream.Clear();
  54. lvJsonStream.Stream.WriteBuffer(lvXMLData[], Length(lvXMLData));
  55. lvJsonStream.setResult(True);
  56. finally
  57. lvDBDataOperator.Free;
  58. end;
  59. finally
  60. //归还连接池
  61. TUniPool.releaseConnObject(lvPoolObj);
  62. end;
  63. //回写数据给客户端
  64. writeObject(lvJsonStream);
  65. end else
  66. begin
  67. //返回数据
  68. writeObject(lvJsonStream);
  69. end;
  70. except
  71. on E:Exception do
  72. begin
  73. lvJsonStream.Clear();
  74. lvJsonStream.setResult(False);
  75. lvJsonStream.setResultMsg(e.Message);
  76. writeObject(lvJsonStream);
  77. end;
  78.  
  79. end;
  80. end;

注释写的比较清楚了,我就不再解释了,其他关联代码可以具体去看各单元的代码。

看看客户端界面。

客户端通过指定帐套ID,告诉服务端应该选用哪个数据库进行操作。

客户端执行的代码

  1. procedure TfrmMain.btnOpenSQLClick(Sender: TObject);
  2. var
  3. lvRecvObj, lvSendObj:TJsonStream;
  4. i, l, lvSize:Integer;
  5. lvData:AnsiString;
  6. begin
  7. lvSendObj := TJsonStream.Create;
  8. lvRecvObj := TJsonStream.Create;
  9. try
  10. lvSendObj.Clear();
  11.  
  12. //帐套ID
  13. lvSendObj.Json.S['config.accountID'] := txtAccount.Text;
  14.  
  15. //执行SQL的命令ID
  16. lvSendObj.Json.I['cmdIndex'] := ;
  17.  
  18. //要执行的SQL
  19. lvSendObj.Json.S['script.sql'] := mmoSQL.Lines.Text;
  20.  
  21. //发送到服务端进行处理<使用Indy进行传输>,如果需要使用ICS,可以在IOCPCoder文件夹中找到对应的uICSClientJSonStreamCoder.pas单元
  22. TIdTcpClientJSonStreamCoder.Encode(self.IdTCPClient, lvSendObj);
  23.  
  24. //接收服务端处理的数据<使用Indy接收数据>
  25. TIdTcpClientJSonStreamCoder.Decode(self.IdTCPClient, lvRecvObj);
  26. if not lvRecvObj.getResult then
  27. begin
  28. raise Exception.Create(lvRecvObj.getResultMsg);
  29. end;
  30.  
  31. //获取数据
  32. SetLength(lvData, lvRecvObj.Stream.Size);
  33. lvRecvObj.Stream.Position := ;
  34. lvRecvObj.Stream.ReadBuffer(lvData[], lvRecvObj.Stream.Size);
  35.  
  36. //放入CDS的XMLDATA
  37. cdsMain.XMLData := lvData;
  38. finally
  39. lvSendObj.Free;
  40. lvRecvObj.Free;
  41. end;
  42. end;

在DIOCP\Demos\IOCPCoder代码中我写了一些客户端的界面和编码器,有ICS,和Indy的,有需要的朋友可以直接引用使用。

基本上差不多了。刚刚群里面的朋友测试在XE4下面测试是通过的,我的环境是D2007。

>>>>>>DIOCP讨论群:320641073

>>>>>>SVN源码和DEMO下载:https://code.google.com/p/diocp/

DIOCP开源项目-数据库连接池的使用<多帐套数据库>的更多相关文章

  1. DIOCP开源项目-高效稳定的服务端解决方案(DIOCP + 无锁队列 + ZeroMQ + QWorkers) 出炉了

    [概述] 自从上次发布了[DIOCP开源项目-利用队列+0MQ+多进程逻辑处理,搭建稳定,高效,分布式的服务端]文章后,得到了很多朋友的支持和肯定.这加大了我的开发动力,经过几个晚上的熬夜,终于在昨天 ...

  2. .NET平台开源项目速览(3)小巧轻量级NoSQL文件数据库LiteDB

    今天给大家介绍一个不错的小巧轻量级的NoSQL文件数据库LiteDB.本博客在2013年也介绍过2款.NET平台的开源数据库: 1.[原创]开源.NET下的XML数据库介绍及入门 2.[原创]C#开源 ...

  3. DIOCP开源项目-DIOCP3的重生和稳定版本发布

    DIOCP3的重生 从开始写DIOCP到现在已经有一年多的时间了,最近两个月以来一直有个想法做个 30 * 24 稳定的企业服务端架构,让程序员专注于逻辑实现就好.虽然DIOCP到现在通讯层已经很稳定 ...

  4. 【DIOCP开源项目】实际应用案例

    案例1 DIOCP是Delphi下进行IOCP服务端通讯开发的一个非常好的开源框架,稳定.高效并且使用起来十分简单. 自己两个多月之前因为需要使用Delphi开发一个TCP服务端,当时也是到处爬文,希 ...

  5. DIOCP开源项目-利用队列+0MQ+多进程逻辑处理,搭建稳定,高效,分布式的服务端

    最近头脑里面一直在想怎么样让能让大家基于DIOCP上写出稳定的服务端程序.很多朋友问我,你DIOCP稳定吗,我可以用他来做三层服务器吗? 当时我是这样回答的,我只能保证DIOCP底层通信的稳定. 说实 ...

  6. DIOCP开源项目-Delphi高性能无锁队列(lock-free)

    最近想在DIOCP中加入任务调度线程,DIOCP的工作线程作为生产者(producer)将接受到的数据对象,投递到任务调度线程中,然后统一进行分配.然而这一切都需要一个队列, 这几天都在关注无锁队列. ...

  7. DIOCP开源项目-DIOCP3 大文件的传输DEMO<断点续传>

    首先该DEMO在StreamCoder上面做的改动,期间导致StreamCoderDEMO经常出现问题,导致大家运行的时候,频频出现问题,表示道歉. 以下是测试的结果,从服务器下载传输了一个3G左右的 ...

  8. DIOCP开源项目-定义自己要发送的数据结构(MyObject)

    印象中网络程序都是sendBuffer和recvBuffer来发送数据和接收数据,本次Demo演示如何定义定义一个自己的对象,然后我们按照OO的思想直接进行对象的发送和接收,先上个流程图. 下面是客户 ...

  9. DIOCP开源项目-DIOCP3的LoadRunner11测试报告

    昨天有个多年的群友(B3.Locet)用LoadRunner11对DIOCP3做压力测试,说测试的时候出现了大量的10053,10054的报告.昨天晚上下载了个LoadRunner11, 今天捣鼓了下 ...

随机推荐

  1. uri.js的用法事例

    来源于:http://smoothprogramming.com/tutorials/get-set-query-string-values-from-url-using-uri-js/ Get or ...

  2. MATLAB 向量

    MATLAB 向量: 1.MATLAB 行向量: 创建行向量括在方括号中的元素的集合,用空格或逗号分隔的元素. 2.MATLAB 列向量: 创建列向量括在方括号中的元素的集合,使用分号来分隔的元素. ...

  3. 【Algorithm】回溯法与深度优先遍历的异同

    1.相同点: 回溯法在实现上也是遵循深度优先的,即一步一步往前探索,而不像广度优先那样,由近及远一片一片地扫. 2.不同点 (1)访问序 深度优先遍历: 目的是“遍历”,本质是无序的.也就是说访问次序 ...

  4. linux中DHCP服务配置文件/etc/dhcpd.conf详细说明

    DHCP服务的配置 dhcpd.conf 是DHCP服务的配置文件,DHCP服务所有参数都是通过修改dhcpd.conf 文件来实现,安装后dhcpd.conf 是没有做任何配置的,将/usr/sha ...

  5. window 10 企业版激活

    一. 用管理员权限打开CMD.EXE 接着输入以下命令: slmgr /ipk NPPR9-FWDCX-D2C8J-H872K-2YT43 弹出窗口提示:“成功的安装了产品密钥”. 继续输入以下命令: ...

  6. Xcode 各版本简介

    1.Xcode 验证 在终端输入 spctl 命令,并带上安装的 Xcode 的路径 $ spctl --assess --verbose /Applications/Xcode.app 之后会看到类 ...

  7. SQL如何获得本季度第一天、一年的第一天、本月的最后一天

    nterval 参数,具有以下设定值: 设置 描述 Year yy, yyyy 年 quarter qq, q 季 Month mm, m 月 dayofyear dy, y 一年的日数 Day dd ...

  8. easyUI设置textbox的值

    我们知道<input type="text" class="easyui-validatebox" id="txtrName" nam ...

  9. 在CentOS上编译安装MySQL 5.7.13步骤详解

    MySQL 5.7主要特性 更好的性能 对于多核CPU.固态硬盘.锁有着更好的优化,每秒100W QPS已不再是MySQL的追求,下个版本能否上200W QPS才是用户更关心的. 更好的InnoDB存 ...

  10. linux中chkconfig 启动程序顺序介绍

    1)redhat的启动方式和执行次序是: 加载内核 执行init程序 /etc/rc.d/rc.sysinit          # 由init执行的第一个脚本 /etc/rc.d/rc $RUNLE ...