The documentation for cx_Oracle 5.0.4 states:
SessionPool.release(/connection/)
Release the connection back to the pool. This will be done
automatically as well if the connection object is garbage collected.
At least with cx_Oracle 5.0.3 (Python 2.6 / win32 / Oracle 10) this is
misleading.
I recently changed a server program using cx_Oracle from using a DIY
dummy-session pool(where acquire always returns a new session and
release always closes the session) to using the cx_Oracle session pool.
As a part of this change, I replaced every occurence of
conn = cx_Oracle.connect(...)
....
conn.close()
with
conn = mysessionpool.acquire()
....
mysessionpool.release(conn)
or mysessionpool.drop(conn) if an cx_Oracle.DatabaseError occured.
Later, I wondered why there were so many sessions in the DB.
And my program hung after a while.
By debugging, I found that mysessionpool.acquire() did not
return when the program hung.
It turned out that in one code location, I forgot to replace
conn.close() with mysessionpool.release(conn).
After changing this line, the program worked.
The cursor object was only referenced by a local variable,
and thus should have been freed after the function ended, I thought.
But obviously that's not the case.
I guess it's not freed (and thus the DB session persists) because
probably the cursor object is still referenced from the SessionPool
object(?)
Conclusion:
While the documentation maybe technically correct, it is at least
misleading.
In order for the DB session to be closed, you must call the SessionPool
release method
(or delete the Session as well as the whole SessionPool object).
So be careful when using the SessionPool.
Henning
|