You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ReleasePreparedCommands method in FbConnectionInternal does not work as expected - does not release resources of all prepared commands upon connection close. [DNET421]
#419
public void ReleasePreparedCommands()
{
for (int i = 0; i < this.preparedCommands.Count; i++)
{
if (!this.preparedCommands[i].IsAlive)
continue;
try
\{
// Release statement handle
\(this\.preparedCommands\[i\]\.Target as FbCommand\)\.Release\(\);
...
}
Collection of preparedCommands that is being processed is changed due to side effect by the FbCommand.Release() call - this function indirectly calls preparedCommands.RemoveAt(i), that causes collection item (index) shifting and changing the Count property value in the for-cycle condition. The change of Count property is not problem. The problem is that unconditional increment of condition control variable "i" at each cycle causes skipping of the item that follows the released one due to mentioned item shifting after RemoveAt(i) method call (item at index "i" is removed, thus following item gets to its position to "fill the gap", but "i" is increased at next for-cycle, so this item is skipped). By other words, if no prepared command was in Alive state, then each even prepared command is properly released.
Due to this bug, not all prepared commands are released - mainly their referenced Statement objects. This could lead to throwing exceptions when core of the driver works with non-properly released resources of FbCommand objects when they are about to be reused after database connection close and not disposed immediately. Such Statement objects are considered valid (but they reference GdsDatabase object that has input and outputStream properties filled with null values etc.) and they are not recreated upon new database connection and executing the reused FbCommand.
One can avoid of this bug, if the FbCommand objects are not reused after connection close (by assigning new Connection and eventually Transaction to them), but diposed and recreated again.
We observed the driver throwing NullPointerExceptions at GdsDatabase.Write() methods when calling FbCommand.ExecuteXXX methods, because FbCommand referenced invalid, previously unreleased Statement object, that referenced invalid old GdsDatabase object.
Submitted by: Jiří Farták (genx)
Is related to DNET291
Here's excerpt of the problematic method:
public void ReleasePreparedCommands()
{
for (int i = 0; i < this.preparedCommands.Count; i++)
{
if (!this.preparedCommands[i].IsAlive)
continue;
...
}
Collection of preparedCommands that is being processed is changed due to side effect by the FbCommand.Release() call - this function indirectly calls preparedCommands.RemoveAt(i), that causes collection item (index) shifting and changing the Count property value in the for-cycle condition. The change of Count property is not problem. The problem is that unconditional increment of condition control variable "i" at each cycle causes skipping of the item that follows the released one due to mentioned item shifting after RemoveAt(i) method call (item at index "i" is removed, thus following item gets to its position to "fill the gap", but "i" is increased at next for-cycle, so this item is skipped). By other words, if no prepared command was in Alive state, then each even prepared command is properly released.
Due to this bug, not all prepared commands are released - mainly their referenced Statement objects. This could lead to throwing exceptions when core of the driver works with non-properly released resources of FbCommand objects when they are about to be reused after database connection close and not disposed immediately. Such Statement objects are considered valid (but they reference GdsDatabase object that has input and outputStream properties filled with null values etc.) and they are not recreated upon new database connection and executing the reused FbCommand.
One can avoid of this bug, if the FbCommand objects are not reused after connection close (by assigning new Connection and eventually Transaction to them), but diposed and recreated again.
We observed the driver throwing NullPointerExceptions at GdsDatabase.Write() methods when calling FbCommand.ExecuteXXX methods, because FbCommand referenced invalid, previously unreleased Statement object, that referenced invalid old GdsDatabase object.
Commits: d00a37a
The text was updated successfully, but these errors were encountered: