Note: This section will not be comprehensible unless you understand the basic characteristics of the Firebird server architectures. These are documented in the “Classic or Superserver?” section of the doc/Firebird-1.5-QuickStart.pdf file included with the Firebird distribution.
Versions of KInterbasDB prior to 3.2 imposed a global lock over all database client library calls. This lock, referred to as the Global Database API Lock (GDAL), must be active for multithreaded client programs to work correctly with versions of the Firebird client library that do not properly support concurrency. Many such versions are still in use, so the GDAL remains active by default in KInterbasDB 3.2. To determine whether the client library you’re using can correctly handle concurrent database calls, read this Overview of Firebird Client Library Thread-Safety.
Note that a single client library might have different thread-safety properties depending on which protocol the client program specifies via the parameters of kinterbasdb.connect(). For example, the Firebird 1.5 client library on Windows is thread-safe if the remote protocol is used, as in
but is not thread-safe if the local protocol is used, as in
KInterbasDB 3.2 supports three levels of concurrency:
Level 1 is the default, so if you don’t understand these subtleties, or are using a client library configuration that is not thread-safe, you do not need to take any action to achieve thread-safety.
Level 2 can greatly increase the throughput of a database-centric, multithreaded Python application, so you should use it if possible. Once you’ve determined that you’re using an appropriate connection protocol with a capable client library, you can activate Level 2 at runtime with the following call:
The kinterbasdb.init function can only be called once during the life of a process. If it has not been called explicitly, the function will be called implicitly when the client program tries to perform any database operation. Therefore, the recommended place to call kinterbasdb.init is at the top level of one of the main modules of your program. The importation infrastructure of the Python interpreter serializes all imports, so calling kinterbasdb.init at import time avoids the potential for multiple simultaneous calls, which could cause subtle problems.
Use the Classic server architecture, but the SuperServer client library. At the time of this writing (December 2005), the thread- centric Vulcan had not been released, so the multi-process Classic architecture was the only Firebird server architecture that could take advantage of multiple CPUs. This means that in most scenarios, Classic is far more concurrency-friendly than SuperServer. The Windows version of Firebird–whether Classic or SuperServer–offers a single client library, so the following advice is not relevant to Windows. The non- Windows versions of Firebird Classic include two client libraries:
- fbclient ( libfbclient.so) communicates with the server solely via the network protocol (possibly over an emulated network such as the local loopback). fbclient is thread-safe in recent versions of Firebird.
- fbembed ( libfbembed.so) uses an in-process Classic server to manipulate the database file directly. fbembed is not thread-safe in any version of Firebird; it should never be used with KInterbasDB concurrency level 2.
At present, the best way to achieve a concurrency-friendly KInterbasDB/Firebird configuration is to use a version of KInterbasDB linked against a thread-safe fbclient, running at concurrency level 2, and communicating with a Classic server. On Linux, such a setup can be created by installing the Classic server, then compiling KInterbasDB with the database_lib_name option in setup.cfg set to fbclient (this is the default setting). A version of KInterbasDB that was linked against fbembed (by setting database_lib_name=fbembed) will not work in a multithreaded program if the concurrency level is higher than 1. On Windows, use a Classic server in combination with one of the standard KInterbasDB Windows binaries for Firebird 1.5 or later, and be sure to set KInterbasDB’s concurrency level to 2.