Multithreading, interbase, firebird 2.1 above 3.5 problem

Discussion of open issues, suggestions and bugs regarding UniDAC (Universal Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
kazhab
Posts: 3
Joined: Tue 27 Dec 2011 08:15

Multithreading, interbase, firebird 2.1 above 3.5 problem

Post by kazhab » Wed 28 Dec 2011 12:53

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.

AndreyZ

Post by AndreyZ » Thu 29 Dec 2011 10:54

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.

kazhab
Posts: 3
Joined: Tue 27 Dec 2011 08:15

Post by kazhab » Thu 29 Dec 2011 12:36

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.

AndreyZ

Post by AndreyZ » Tue 03 Jan 2012 10:42

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.

Post Reply