感谢竹子!

整体思路,是不用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. 微软职位内部推荐-Senior Dev Lead

    微软近期Open的职位: Bing Index Serve team is hiring! We are one of the core teams in Bing serving more than ...

  2. google calendar

    1. user guide on google https://developers.google.com/google-apps/calendar/instantiate 2. google app ...

  3. Jquery.linq 使用示例

    http://linqjs.codeplex.com/ /*Linq JS*/ //range var aa = Enumerable.range(1, 10).toArray(); var kk = ...

  4. eclipse svn 修改了类名之后提交

    win下面的文件名不区分大小写,所以不能只是把小写类名改成大写. 正确的做法有如下两种:1,先删除类a,提交,此操作会删除服务器上的文件.再添加类A,提交.2,重命名a为aa,提交,此操作会删除服务器 ...

  5. oracle 条件:1=1或1=0,动态添加条件

    看到where语句中有条件:where 1=1    和    1=2或1<>1 用途:     1=1:是为了添加条件时使用and并列其他条件时使用的(动态连接后续条件)     比如: ...

  6. 140304笔记, mysql 更改自动增长字段值的重新设定

    1. 存在同名的或不同的namespace交错情况. Caused by: com.ibatis.sqlmap.client.SqlMapException: There is no result m ...

  7. hadoop浅尝 第一个hadoop程序

    hadoop编程程序员需要完成三个类. map类,reduce类和主类. map和reduce类自然是分别完成map和reduce.而主类则负责对这两个类设置job.完成这三个类之后,我们生成一个ja ...

  8. hdu 1757 A Simple Math Problem (矩阵快速幂,简单)

    题目 也是和LightOJ 1096 和LightOJ 1065 差不多的简单题目. #include<stdio.h> #include<string.h> #include ...

  9. eclipse 或MyEclipse将工程进行移动的时候会对@Override报错的处理方法

    有时候导入javaSE,javaEE,android 工程的时候,明明是刚刚用过的没有问题的工程,但重新导入的时候就报错. 提示The method ... must override a sperc ...

  10. C#实现身份证号码验证的方法

    本文实例讲述了C#实现身份证号码验证的方法.分享给大家供大家参考.具体实现方法如下: 随着现在互联网的发展,越来越多的注册用户的地方都用到了身份证,那么对于输入的身份证如何验证呢?看下面的代码,其实很 ...