カーソルクローズ

解決


りべら  2005-05-12 05:11:38  No: 14757

初めて質問させていただきます。
宜しくお願いします。

下記の現象に悩んでいます。

1.TSQLQueryを利用してOracleへSQLを発行
2.TSQLQueryをオープン
3.TSQLQueryをクローズ
結果:ORACLE上にカーソルが残留し、最後には「ORA-01000:カーソルが最大カーソル数を超えています」のメッセージが発生。

TSQLQuery.Closeよりソースを追っていくと

procedure TDataSet.CloseCursor;
begin
  BlockReadSize := 0;
  FInternalOpenComplete := False;
  FreeFieldBuffers;
  ClearBuffers;
  SetBufListSize(0);
  InternalClose;  ←カーソル開放されず。(Openの場合はInternalOpenでカーソルが増える)
  FBufferCount := 0;
  FDefaultFields := False;
end;

結果的にDELPHIのバグかと思うのですが、対処方法を知ってる方は
お願い致します。

[環境]
OS:Windows2000
DB:Oracle9i


RAN  2005-05-14 16:01:18  No: 14758

open_cursorsを増やすか、データベースの接続を切って再接続すればよいのでは?

接続方法(dbExpress?)やDelphiのバージョン。パッチの適用状況などを
明示した方がレスがつきやすいと思いますよ。


りべら  2005-05-16 19:16:52  No: 14759

RANさん、ご返信有難うございます。
ご指摘の通り今更ながら環境を追記致します。

DELPHI 7 (build 8.1) アップデート7.1
DB:ORACLE 9i (カーソルの最大値は100に設定)
OS:Windows2000 SP4

接続方法と致しましては、セッションは常時接続したまま、コネクションプールを利用し使いまわしています。
※コネクションプールには海外製のTDBXConnectionPoolを使用。

ロジック的な部分としては

try
  query1.clese;
  query1.sql.clear;
  query1.sqlconnection := ConnectionPoolFactory.GetSQLConnection;←プール取得

  query1.sql.add('select sysdate from dual');
  query1.open;
  //取得処理

finally
  query1.close;
  ConnectionPoolFactory.FreeSQLConnection(sqqCmnt.SQLConnection);←プールを返す
end;

Open時にはカーソルが増え、Closeでカーソルを開放せず。
いろいろ調べてみるとCloseを追っていったInternalCloseでカーソルをクローズするみたいな事が書いてあるのに開放せず。
TSQLConnectionを利用しても駄目。

ORACLEのRAC機能を利用する為にセッションは常時接続で行いたい。

以上、皆様のお知恵を拝借したく宜しくお願い致します。


RAN  2005-05-18 10:06:44  No: 14760

どなたも回答がないようですので、しゃしゃり出ます。

過去ログを調べてみた所、クライアント側でカーソルを閉じても
サーバー側ではすぐにカーソルを閉じない、というのは普通のことみたい
です。Oracleの最適化の問題だそうです。

プーリングする場合は、カーソルを再利用するみたいですが
TDBXConnectionPoolではどうなっているのでしょう?
まずは作者に問い合わせてみたらどうでしょう?


りべら  2005-05-19 00:46:59  No: 14761

RANさん、ご回答有難うございます。

調査してみたところ、

  q := TSQLQuery.Create(self);
  try
    q.SQLConnection := SQLConnection1;
    for i := 0 to 100 do begin
      q.Close;
      q.SQL.Clear;
      q.SQL.Add('select sysdate from dual');
      q.Open;
      q.Close;
    end;
  finally
   q.Free;
  end;
→TSQLQUeryをFreeするとカーソル自体は消えていませんが、
  次のクエリー生成後のOPENでもカーソルは積み上げられないこと
  がわかりました。

    for i := 0 to 99 do begin
      q := TSQLQuery.Create(self);
      q.SQLConnection := SQLConnection1;
      q.Close;
      q.SQL.Clear;
      q.SQL.Add('select sysdate from dual');
      q.Open;
      q.Close;
      ol.Add(q);
    end;
    ol.free;
→カーソルが100まで増えてフリーされてもカーソルは100のままですが、
  再度この処理を通すと1回目のOpen時にカーソル数は1になります。

Free後のOpenで何らかのクリア処理が行われているのかどうかなどはまだ
調査段階です。

Openの処理内容によってはDBExpressの仕様(バグ?)とかの段階になってしまう
と思いますので、これにてとりあえずの解決としたいと思います。

調査結果、対応方法がわかり次第今後に役立つかわかりませんが再度
書き込み致します。

RANさん、説明不備、乱文の質問にお答えいただき有難うございましたm(_ _)m


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加