DB Interface Module User’s Guide : PART III Using Advanced Features : Chapter 11 Multithreading : Sharing an RWDBConnection
Sharing an RWDBConnection
Sharing an RWDBConnection object among threads requires caution. Many non-sharable DB Interface Module objects, such as RWDBStoredProc, RWDBCursor, or RWDBResult, cache the connections that are passed to them upon creation or execution. This caching remains in effect until a new association is made or until the objects are destroyed. You must take care to remove all other associations of the connection with other nonsharable objects before the connection is released to other threads. A simple way to do this is to ensure that the nonsharable objects are destroyed before the connection is released. The following code sample illustrates the problem.
Note that in the following example we have used acquire() and release() just to illustrate the problem. In general, we recommend that you use guard classes.
Example 12 – Sharing an RWDBConnection among threads
RWDBConnection sharedConn; // Globally visible.
// Assume it is set somewhere.
 
void foo(const RWDBDatabase& database) {
sharedConn.acquire(); //1
RWDBStoredProc sp =
database.storedProc(“myProc”, sharedConn); //2
sp.execute(sharedConn); //3
sharedConn.release(); //4
... //5
}
It appears that the code above is doing everything correctly. The shared connection is locked until the execution of the stored procedure, and then released so that other threads can gain access to it. This procedure seems good, but there is a problem. The call in //3 returns an RWDBResult. Though the application does not catch this return value, the created RWDBResult object holds the results of the execution. In other words, the shared connection is still busy. This will be true until the RWDBResult object and the RWDBStoredProc object are destroyed. Until then, the shared connection should not be released for access to other threads. The following code sample fixes the problem.
 
RWDBConnection sharedConn; // Globally visible.
// Assume it is set somewhere.
 
void foo(const RWDBDatabase& database) {
sharedConn.acquire(); //1
{ //2
RWDBStoredProc
sp = database.storedProc(“myProc”, sharedConn); //3
sp.execute(sharedConn); //4
} //5
sharedConn.release(); //6
... //7
}
By scoping the life of the RWDBStoredProc object (//2 and //5), we ensure that the RWDBStoredProc object and the RWDBResult it returns are destroyed before the shared connection is released for access to other threads.