Page 1 of 1

Bug in multithreaded environment

Posted: Thu 09 Mar 2006 13:58
by szakalyb
Hello!

The situation is very simple:

Create two thread. In thread's execute, create a connection, and run a long running SQL command.
While it running, the second thread's connection cannot connect or run any SQL.

I this this is a very unacceptable and critical bug.

platform: Delphi6, WinXP, Ora8.1.7

here is a very simple code:

You need enter to memo1 any long running SQL, and press Button1 twice.
The second thread's connect will wait while the first thread's sql end.

[email protected]

Code: Select all


unit frm_Main;

interface

uses
  SyncObjs, DBxpress, SQLExpr, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
  Forms, Dialogs, ExtCtrls, Menus, StdCtrls;

type
  TSQLExecThread = class(TThread)
  protected
    Command: String;
    TranDesc: TTransactionDesc;
    Connection: TSQLConnection;
    Dataset: TSQLDataSet;
    procedure Execute; override;
  public
    constructor Create;
  end;

  TFrmMain = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  public
  end;

var
  FrmMain: TFrmMain;

implementation

uses DB;

const
  GTranID: Integer = 1;

{$R *.dfm}

function CreateConnection: TSQLConnection;
begin
  Result := TSQLConnection.Create(nil);

  Result.LoadParamsOnConnect := False;
  Result.SQLHourGlass := False;
  Result.LoginPrompt := False;
  Result.DriverName := 'ORACLE';

  Result.GetDriverFunc := 'getSQLDriverORA';
  Result.LibraryName := 'dbexpoda.dll';
  Result.VendorLib := 'OCI.DLL';
  Result.Params.Text :=
            'BlobSize=-1'#13#10+
            'ErrorResourceFile='#13#10+
            'LocaleCode=0000'#13#10+
            'Oracle TransIsolation=ReadCommited'#13#10;

  Result.Params.Values['Database'] := 'ORCL';
  Result.Params.Values['Password'] := 'XX';
  Result.Params.Values['User_Name'] := 'XX';
end;

function CreateDataset(AConnection: TSQLConnection; ACommand: string): TSQLDataSet;
begin
  Result := TSQLDataSet.Create(nil);
  with Result do
  begin
    SQLConnection := AConnection;
    NoMetadata := True;
    CommandText := ACommand;
  end;
end;

procedure TFrmMain.Button1Click(Sender: TObject);
begin
  TSQLExecThread.Create;
end;

{ TSQLExecThread }

constructor TSQLExecThread.Create;
begin
  Command := FrmMain.Memo1.Text;
  inherited Create(False);
  FreeOnTerminate := True;
end;

procedure TSQLExecThread.Execute;
begin
  FillChar(TranDesc, SizeOf(TranDesc), 0);
  TranDesc.TransactionID := GTranID;
  Inc(GTranID);
  TranDesc.IsolationLevel := xilREADCOMMITTED;

  Connection := CreateConnection;
  try
    Connection.Open;
    Dataset :=  CreateDataset(Connection, Command);
    try
      Dataset.Open;
    finally
      Dataset.Free;
    end;
  finally
    Connection.Free;
  end;
end;

end.
[/code]

Posted: Fri 10 Mar 2006 09:39
by Challenger
We modified your example in order to get some information about threads execution and tested it in the following case:
1. Complicated SQL statement with execution time about 10 seconds
2. SELECT * FROM EMP
We got the following results:
Thread 1 Connected
Thread 2 Connected
Thread 2 Executed
And after 10 seconds delay
Thread 1 Executed
Thus we couldn't reproduce your problem. Please send to DbxOda support address sample that demonstrates it including scripts to create server objects.

Posted: Fri 10 Mar 2006 15:37
by szakalyb
Hi!

I sent (alexh@...) demo app, which demonstrate this situation.