Page 1 of 1

Multithreading, interbase, firebird 2.1 above 3.5 problem

Posted: Wed 28 Dec 2011 12:53
by kazhab
For long time I have been working with UNIDAC version 3.5.12 . had no major problems thus far.

Due to need for compatibility with postgresql 9.1 database, Just recently instaled latest version of unidac 4.1.3. and in one of my projets noticed that interbase query's are dramaticaly slower than using old 3.5 version of unidac.

Am suspecting that problem lies in multithreading.

Application usualy executes procedure which creates average 20 seperate threads with tuniconection, tunitransaction and tuniquery in each, connecting to seperate remote databases for each thread and collecting large ammount of data.

Previously, total ammount of completed query requests where average 200-1000 results per second from all threads simultaneously. But after instaling latest unidac version, it dropet to average 11/s not matering how many simultaneous threads where runing, except when only one was executed, query speed was acceptable for that one single connection.

Have read that since ibdac version 3.6 there was added another property for safe multithreading using parameters EnsureThreadSafet or ThreadSafetyClientLibrary. So I am wondering if there must be a similar parameter for UNIDAC uniconnection which must be adjusted so that application runs as it was with previous versions of unidac.

Am curently using delphi 2010 with latest unidac 4.1.3 and Firebird versions varying from 1.5 to 2.1.3 (mostly 2.1.2).

Would be thankful for quick solution for this problem, I can provide with a small demo project if it will be necesary.

Posted: Thu 29 Dec 2011 10:54
by AndreyZ
Hello,

Please try the following:
- add the IBCCallUni unit to the USES clause of your unit;
- use the following code:

Code: Select all

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  List: TList;
  i: integer;
begin
  UniConnection.Open;
  List := GDSList.LockList;
  try
    for i := 0 to List.Count - 1 do
      TGDS(List[i]).EnsureThreadSafety := False;
  finally
    GDSList.UnlockList;
  end;
end;
Does it solve the problem? If not, please send your demo project to andreyz*devart*com.

Posted: Thu 29 Dec 2011 12:36
by kazhab
Many thanks,
The code you provided, did solve this problem.

Question, does that mean that I must run this after every opened connection and that it sets every active connections EnsureThreadSafety variable to false?

I hope that in near future there will be more elegant way to change this property for certain connections only :wink:

if there will be any other problem regarding this solution, i'll post soon.

Thank you AndreyZ.

Posted: Tue 03 Jan 2012 10:42
by AndreyZ
If you are using only one Firebird client library at a time, you should call this code once when your application starts working.
Firebird versions that you are using have not thread-safe client libraries. Using these libraries in multithreaded application can cause numerous errors. To avoid these errors, we implemented thread safety for Firebird and InterBase on our own. Thread safety is implemented for client libraries but not for connections. We don't see the necessity of choosing thread safety for each connection.