感谢竹子!

整体思路,是不用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.

清幽傲竹实现kbmMWServer的方法(转)的更多相关文章

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

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

  2. 移动开发的框架(用Firepower,不用listview,超快) good

    我是通过http传送xml后台是阿帕奇的http server,后台可以用delphi或php 都可以.用post 刚才试了试自带的TNetHttpClient,感觉还好,代码封装也不算深,收发数据也 ...

  3. xalion三层与Web开发帖子一览表 good

    使用http.sys,让delphi 的多层服务飞起来(Delphi借用http.sys充当http服务器,也就可以发送返回JSON等信息,当然浏览器也可以使用)http://www.cnblogs. ...

  4. 初识kbmmw 中的ORM

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

  5. javaSE27天复习总结

    JAVA学习总结    2 第一天    2 1:计算机概述(了解)    2 (1)计算机    2 (2)计算机硬件    2 (3)计算机软件    2 (4)软件开发(理解)    2 (5) ...

  6. mapreduce多文件输出的两方法

    mapreduce多文件输出的两方法   package duogemap;   import java.io.IOException;   import org.apache.hadoop.conf ...

  7. 【.net 深呼吸】细说CodeDom(6):方法参数

    本文老周就给大伙伴们介绍一下方法参数代码的生成. 在开始之前,先补充一下上一篇烂文的内容.在上一篇文章中,老周检讨了 MemberAttributes 枚举的用法,老周此前误以为该枚举不能进行按位操作 ...

  8. IE6、7下html标签间存在空白符,导致渲染后占用多余空白位置的原因及解决方法

    直接上图:原因:该div包含的内容是靠后台进行print操作,输出的.如果没有输出任何内容,浏览器会默认给该空白区域添加空白符.在IE6.7下,浏览器解析渲染时,会认为空白符也是占位置的,默认其具有字 ...

  9. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

随机推荐

  1. How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically?

    The more general extension of ViewPager would bet to create a "SetPagingEnabled" method so ...

  2. Careercup - Facebook面试题 - 6026101998485504

    2014-05-02 10:47 题目链接 原题: Given an unordered array of positive integers, create an algorithm that ma ...

  3. HTTP - 内容编码

    HTTP 应用程序有时在发送之前需要对内容进行编码.例如,在把很大的 HTML 文档发送给通过慢速连接上来的客户端之前,服务器可能就会对它进行压缩,这样有助于减少传输实体的时间. 内容编码过程 内容编 ...

  4. js获取对象、数组的实际长度,元素实际个数

    /*获取对象.数组的长度.元素个数 *@param obj 要计算长度的元素,可以为object.array.string */ function count(obj){ var objType = ...

  5. iOS Core data多线程并发访问的问题

    大家都知道Core data本身并不是一个并发安全的架构:不过针对多线程访问带来的问题,Apple给出了很多指导:同时很多第三方的开发者也贡献了很多解决方法.不过最近碰到的一个问题很奇怪,觉得有一定的 ...

  6. 3640: JC的小苹果 - BZOJ

    让我们继续JC和DZY的故事.“你是我的小丫小苹果,怎么爱你都不嫌多!”“点亮我生命的火,火火火火火!”话说JC历经艰辛来到了城市B,但是由于他的疏忽DZY偷走了他的小苹果!没有小苹果怎么听歌!他发现 ...

  7. vi之跳到指定行

    vi里怎样跳转到某一指定行 输入 :行号 :$跳到最后一行 gg跳到第一行.

  8. windows下几种I/O端口(了解)

    如果你想在Windows平台上构建服务器应用,那么I/O模型是你必须考虑的.Windows操作系统提供了选择(Select).异步选择(WSAAsyncSelect).事件选择(WSAEventSel ...

  9. 【ACMER纷纷表示】女生应该找一个玩ACM的男生

    1.强烈的事业心 将来,他也一定会有自己热爱的事业.而且,男人最性感的时刻之一,就是他专心致志做事的时候.所以,找一个机会在他全神贯注玩ACM的时候,从侧面好好观察他,你就会发现我说的话没错.2.永不 ...

  10. Unity3d集成移动MM SDK 2.2的技术要点(坑爹的MM SDK)

    原地址:http://dong2008hong.blog.163.com/blog/static/4696882720140423517951/ U3D集成移动MM的SDK绝对是以坑爹为主的东西. 浪 ...