#1 2012-04-25 12:28:13

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,571
Website

TOleDBConnection and multithread

Refer to ticket http://synopse.info/fossil/tktview?name=213544b2f5.
The problem is more complex:
Call to TSQLDBConnectionPropertiesThreadSafe.ThreadSafeConnection usually made from inside HTTPserver thread, and corresponding CoInitialize call in HTTPserver thread context.
Call to TSQLDBConnectionPropertiesThreadSafe.Destroy is made from main thread, therefor call to CoUnInitialize is not made from thread in witch CoInitialize called.
As result we have "Missing TOleDBConnection.Destroy call in" in SynOleDB.finalization

The solution is to define event like THttpServerGeneric.OnHTTPThreadTerminate. (OnTerminate is unusable because of Synchronize)

With such type of event a write something like:

procedure MyServer_OnHTTPThreadTerminate(sender: TObject);
begin
  fMyCnnProp.EndCurrentThread;
end;

Arnaud, I sent patched SynCrtSock.pas for you.

Offline

#2 2012-04-25 14:30:36

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,655
Website

Re: TOleDBConnection and multithread

Nice catch.

I've added a new THttpServerGeneric.OnHttpThreadTerminate event, available to clean-up any process in the thread context, when it is terminated (to call e.g. TSQLDBConnectionPropertiesThreadSafe.EndCurrentThread in order to call CoUnInitialize from thread in which CoInitialize was initialy made).
See http://synopse.info/fossil/info/b2e16aae7d

I guess in this case, the assert(OleDBCoinitialized>0) in SynOleDB.CoUninit is not triggered any more, right?
I've made the assertion message much more explicit, in order to state that there is an error in the thread implementation, and the new THttpServerGeneric.OnHttpThreadTerminate event should be used, if necessary.

Thanks a lot for the feedback!

Offline

#3 2012-04-25 15:15:56

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,571
Website

Re: TOleDBConnection and multithread

Yes, now all OK. Thanks!

Offline

#4 2012-07-06 15:04:34

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,571
Website

Re: TOleDBConnection and multithread

AB, Hi!
I found some problems in mORMot when use TSQLDBConnectionProperties.GetFields and other database-structure related methods with TSQLDBConnectionPropertiesThreadSafe descendants.
These methods use MainConnection to get database structure, but in multithread (TSQLDBConnectionPropertiesThreadSafe ) it's not good, even with  OleDB.
The solution I propose is to make function TSQLDBConnectionProperties.GetMainConnection virtual and override it in

function TSQLDBConnectionPropertiesThreadSafe.GetMainConnection: TSQLDBConnection;
begin
  Result := ThreadSafeConnection;
end;

This will solve problem in easiest way.

I write a ticket for tracking.

Offline

#5 2012-07-06 15:40:23

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,655
Website

Re: TOleDBConnection and multithread

Offline

#6 2013-11-02 15:29:04

畅雨
Member
Registered: 2013-10-24
Posts: 29

Re: TOleDBConnection and multithread

ad,
       I do not use THttpServerGeneric ,only use olednconnection ,how can i  free it? sad
       help

     code:
        ...
        fDefaultConnectionProperties:=TOleDBMSSQL2012ConnectionProperties.Create('.','database','sa','');
        fDefaultConnectionProperties.Execute(sql,param);
        freeandnil(fDefaultConnectionProperties) ;
        .... 
       
     When exit application, the process  can not be terminated.

Last edited by 畅雨 (2013-11-02 16:40:25)

Offline

#7 2013-11-02 22:32:35

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,655
Website

Re: TOleDBConnection and multithread

The statement interface should be released before freeing connection properties.

Offline

#8 2013-11-03 01:38:10

畅雨
Member
Registered: 2013-10-24
Posts: 29

Re: TOleDBConnection and multithread

Oh,but ,not do it :(
     When exit application, sometime  the process  can not be terminated, sometime trancing to here:
---->
assert(OleDBCoinitialized>0,'You should call TOleDBConnection.Free from the same '+
    'thread which called its Create: i.e. call MyProps.EndCurrentThread from an '+
    'THttpServerGeneric.OnHttpThreadTerminate event - see ticket 213544b2f5');
  dec(OleDBCoinitialized);
  if OleDBCoinitialized=0 then
    CoUninitialize;

Offline

#9 2013-11-03 01:47:52

畅雨
Member
Registered: 2013-10-24
Posts: 29

Re: TOleDBConnection and multithread

My  test code (delphi7):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,synoledb, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    MSSQL2012OLEDB:TOleDBMSSQL2012ConnectionProperties;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
   MSSQL2012OLEDB:=TOleDBMSSQL2012ConnectionProperties.Create('.','dh1pmip','sa','');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MSSQL2012OLEDB.Execute('select 1 as  aa',[]);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  MSSQL2012OLEDB.Free;
end;

Click button1, run MSSQL2012OLEDB.Execute,   
When exit application, the process  can not be terminated.

Offline

#10 2013-11-04 18:02:55

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,655
Website

Re: TOleDBConnection and multithread

I just performed tests for MS SQL Server, with no problem.
I used SQLExpress 2008 R2 via OleDB.
It is now supported by the "15 - External DB performance" sample.
Performance is pretty amazing.
See http://blog.synopse.info/post/2013/11/0 … ing-MS-SQL

Also fixed some issues with the SQL generated by the ORM for index creation.
See http://synopse.info/fossil/info/63b6db715d

Offline

Board footer

Powered by FluxBB