感谢竹子!

整体思路,是不用kbmMWUNIDACQuery,而是直接用uniQuery做数据查询,利用kbmMWUNIDACConnectioPool取得数据库联接,自己再建一个uniQuery对象池,从中取uniQuery.
下面是一个具体查询数据库的方法:
function TSchoolSrv.PerformGetStuAttendanceState(
  ClientIdent: TkbmMWClientIdentity;
  const Args: array of Variant): Variant;
var
  aUniQuery: TUniQuery;
  aconn: TkbmMWUNIDACConnection;
  json: string;
  code: Integer;
  msg: string;
  student_name,class_name: string;
  memTable: TkbmMemTable;
  aStreamFormat: TkbmMWBinaryStreamFormat;
begin
  code := -1;
  memTable := nil;
  aUniQuery := nil;
  aStreamFormat := nil;  
  aconn := FDM.getkbmMWUNIDACConnection;
  if aconn = nil then  kbmMWRaiseException(101,'无可用的数据库连接.');

try
      aUniQuery := UniQueryPool.Lock;
      if aUniQuery = nil then kbmMWRaiseServerException('无可用的数据集对象.');

aUniQuery.Connection := aconn.Database;
      aUniQuery.SQL.Text := 'select attendance_state_code,attendance_state from attendance.stu_attendance_state';
      aUniQuery.sql.Text := fdm.getFinalSql(aUniQuery.sql.Text);//多库合一库时重组SQL语句
      aUniQuery.Open;
      memTable := kbmMemTablePool.Lock;
      if memTable = nil then kbmMWRaiseServerException('无可用的内存表对象.');
      memTable.LoadFromDataSet(aUniQuery,[mtcpoStructure,mtcpoProperties]);
      aStreamFormat := kbmMWBinaryStreamFormatPool.Lock;
      if aStreamFormat = nil then  kbmMWRaiseServerException('无可用的StreamFormat对象.');
      memTable.SaveToStreamViaFormat(ResultStream,aStreamFormat);
    except
      on e: Exception do
      begin
         kbmMWRaiseException(999,e.Message);
      end;  
    end;

finally
    if aUniQuery <> nil then UniQueryPool.UnLock(aUniQuery);
    if memTable <> nil then kbmMemTablePool.UnLock(memTable);
    if aStreamFormat <> nil then kbmMWBinaryStreamFormatPool.UnLock(aStreamFormat);
    aconn.UnlockConnection;
  end;
end;

下面这个方法,从kbmMWUNIDACConnectionPool取得一个可用的数据库联接.function TFDM.getkbmMWUNIDACConnection: TkbmMWUNIDACConnection;

begin
  Result := TkbmMWUNIDACConnection(kbmMWUNIDACConnectionPool1.GetBestConnection(True,0,nil,3000));
end;

最后,再看看uniQuery池管理对象的实现,整个单元,不多解释.

unit UUniQueryPool;

interface

uses
  Classes, Windows, SysUtils, Uni, forms;

type
  TUniQueryPool = class(TObject)
  private
    FObjList:TThreadList;
    FTimeout: Integer; //单位:毫秒
    FMaxCount: Integer;
    FSemaphore: Cardinal;
    function CreateNewInstance(List:TList): TUniQuery;
    function GetLock(List:TList;Index: Integer): Boolean;
    function getUsedCount: Integer;
  public
    property Timeout:Integer read FTimeout write FTimeout;
    property MaxCount:Integer read FMaxCount;
    property usedCount: integer read getUsedCount;

constructor Create(ACapicity:Integer);overload;
    destructor Destroy;override;
    function Lock: TUniQuery;
    procedure UnLock(var Value: TUniQuery);
  end;

var
  UniQueryPool: TUniQueryPool;

implementation

constructor TUniQueryPool.Create(ACapicity:Integer);
begin
  FObjList:=TThreadList.Create;
  FTimeout := 3000;
  FMaxCount := ACapicity;
  FSemaphore := CreateSemaphore(nil, FMaxCount, FMaxCount, nil);   
end;

function TUniQueryPool.CreateNewInstance(List:TList): TUniQuery;
var
  p: TUniQuery;
begin
  try
    p := TUniQuery.Create(nil);
    p.Tag := 1;
    List.Add(p);
    Result := p;
  except
    Result := nil;
    Exit;
  end;
end;

destructor TUniQueryPool.Destroy;
var
  i: Integer;
  List:TList;
begin
  List:=FObjList.LockList;
  try
    for i := List.Count - 1 downto 0 do
    begin
      TUniQuery(List[i]).Free;
    end;
  finally
    FObjList.UnlockList;
  end;
  FObjList.Free;
  FObjList := nil;
  CloseHandle(FSemaphore);
  inherited Destroy;
end;

function TUniQueryPool.GetLock(List:TList;Index: Integer): Boolean;
begin
  try
    Result := TUniQuery(List[Index]).Tag = 0;
    if Result then
      TUniQuery(List[Index]).Tag := 1;
  except
    Result :=False;
    Exit;
  end;
end;

function TUniQueryPool.getUsedCount: Integer;
var
  i: Integer;
  List:TList;
begin
  try
    Result := 0;
    list := FObjList.LockList;
    Result := list.Count;
  finally
    FObjList.UnlockList;
  end;  
end;

function TUniQueryPool.Lock: TUniQuery;
var
  i: Integer;
  List:TList;
begin
  try
    Result := nil;
    if WaitForSingleObject(FSemaphore, Timeout) = WAIT_FAILED then Exit;
    List:=FObjList.LockList;
    try
      for i := 0 to List.Count - 1 do
      begin
        if GetLock(List,i) then
        begin
          Result := TUniQuery(List[i]);
          //PostMessage(Application.MainForm.Handle, 8888,23,0);
          Exit;
        end;
      end;
      if List.Count < MaxCount then
      begin
        Result := CreateNewInstance(List);
        //PostMessage(Application.MainForm.Handle, 8888,21,0);
      end;
    finally
      FObjList.UnlockList;
    end;
  except
    Result :=nil;
    Exit;
  end;
end;

procedure TUniQueryPool.Unlock(var Value: TUniQuery);
var
  List:TList;
begin
  try
    List:=FObjList.LockList;
    try
      TUniQuery(List[List.IndexOf(Value)]).Tag :=0;
      ReleaseSemaphore(FSemaphore, 1, nil);
    finally
      FObjList.UnlockList;
    end;
    //PostMessage(Application.MainForm.Handle, 8888, 22, 0);
  except
    Exit;
  end;
end;

initialization
  UniQueryPool := TUniQueryPool.Create(100);
finalization
  FreeAndNil(UniQueryPool);

end.

转载于:https://www.cnblogs.com/cpprun/p/4724858.html

清幽傲竹实现kbmMWServer的方法(转)相关推荐

  1. 清幽傲竹实现的kbmMWServer数据库联接失败重联(转载红鱼儿)

    1.修改kbmMWUnidac单元的TkbmMWUNIDACConnection.InternalOpenConnection方法,加上: //支持unidac重联           FDataba ...

  2. 使用http.sys,让delphi 的多层服务飞起来

    一直以来,delphi 的网络通讯层都是以indy 为主,虽然indy 的功能非常多,涉及到网络服务的 各个方面,但是对于大多数多层服务来说,就是需要一个快速.稳定.高效的传输层.Delphi 的 d ...

  3. 初识kbmmw 中的ORM

    在kbmmw 5.02.1 中,加入了ORM 的功能(这里可能和其他语言的定义不完全一样),我们就简单的认为 它就是一个类与数据库的转换吧.今天就先介绍一下如何通过kbmmw 的ORM 功能,实现类与 ...

  4. 在 Oracle Enterprise Linux 和 iSCSI 上构建您自己的 Oracle RAC 11g 集群

    作者:Jeffrey Hunter 了解如何以低于 2,700 美元的费用在 Oracle Enterprise Linux 上安装并配置 Oracle RAC 11g 第 2 版开发集群. 本指南中 ...

  5. Java面试题大全2021版

    一.Java 基础 JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境. JRE:Java Run ...

  6. Kotlin协程使用,协程使用注意事项,协程中的await方法使用|不使用suspend使用协程

    参见 码云 协程使用方法一 (Dispatchers调度器模式) 指定不同线程.同线程会挂起并阻塞(挂起是不影响主线程执行,阻塞是同样的IO线程会阻塞) withContext(Dispatchers ...

  7. IDEA中将代码块封装为方法,IDEA代码重构快捷键

    IDEA中将代码块封装为方法 选中要转换的代码块,快捷键: Windows快捷键:Alt + Shift + M Mac快捷键:Alt + Command + M 如图:

  8. IDEA自动生成对象所有set方法

    idea中有一款插件能够生成对象所有的set方法,GenerateAllSetter :下载地址 步骤1:将下载好的压缩包放在自己记得的文件夹中,在idea中进行导入 步骤2:在本地选中刚才的压缩包, ...

  9. List元素互换,List元素转换下标,Java Collections.swap()方法实例解析

    Java Collections.swap()方法解析 jdk源码: public static void swap(List<?> list, int i, int j) {// ins ...

最新文章

  1. pandas中dataframe默认不显示所有的数据行(中间省略)、使用option_context函数自定义设置单个dataframe允许显示的行的个数、set_option函数全局设置显示行的个数
  2. odbc远程连接mysql_无法使用unixodbc,libmyodbc连接到远程mysql服务器
  3. 遇到oracle错误1012,跟着感觉走,解决安装RAC过程中OCR完整性错误,待深入剖析...
  4. 【java】java getOrDefault 方法的一个坑,容易导致OOM
  5. HDU 3081Marriage Match II(二分法+并检查集合+网络流量的最大流量)
  6. Cocos2d-X中国象棋的发展《五岁以下儿童》摆棋
  7. ios 数字键盘左下角添加按钮_ios数字键盘添加完成按钮
  8. Q130:PBRT-V3,非均匀介质的采样(11.3.3章节、15.2.2章节)
  9. 正文内容 SQL Server 数据库清除日志
  10. 【生信进阶练习1000days】day16~day22-RNA-seq data analysis with limma edgeR and Glimma
  11. Securing Big Data Provenance for Auditors: The Big Data Provenance Black Box as Reliable Evidence
  12. PROFINET 链路简述
  13. win10计算机无限弹网页,Win10老弹出窗口怎么回事?Win10持续闪现神秘窗口现象的解决办法...
  14. 基于火焰传感器的火焰警报
  15. 简单的手机html页面源代码,手机页面h5的简单demo
  16. can总线程序讲解_详解CAN总线
  17. vue报错[wds] disconnected
  18. Docker、Docker file、Docker-compose 详解
  19. IOC的概念和原理:什么是IOC?、IOC的底层原理、图示、IOC接口介绍
  20. Junit、Json和kv结构的相互转化

热门文章

  1. 热身赛—H - 扫雷?踩雷!!
  2. 回归分析结果表格怎么填_Excel回归分析结果的详细阐释
  3. 文献阅读二—Robsut Wrod Reocginiton via Semi-Character Recurrent Neural Network
  4. 【图文教程】CAD 卸载工具(免费),教你卸载CAD
  5. hosts.deny
  6. g++ stray 错误
  7. javaweb新闻管理系统03
  8. 几种常用开发语言的对比
  9. 图片滚动...............
  10. 玩家真正需要什么 游戏系统的必要性浅谈