New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error invalid transaction handle [DNET87] #100
Comments
Modified by: Ralf Giese (rgiese)Attachment: Demo.cs [ 10320 ] |
Modified by: Ralf Giese (rgiese)environment: Firebird CS 1.5.3.4870 => Firebird Superserver 1.5.3.4870 |
Modified by: @carlosgastatus: Open [ 1 ] => In Progress [ 3 ] |
Modified by: @carlosgapriority: Major [ 3 ] => Critical [ 2 ] Version: 2.1.0 Beta 2 [ 10120 ] Version: 2.1.0 Beta 1 [ 10110 ] Version: 2.0.1 [ 10101 ] Version: 2.0.1 RC2 [ 10080 ] Version: 2.0.1 RC 1 [ 10070 ] Version: 2.1.0 Beta 3 [ 10140 ] Fix Version: 2.1.0 RC 1 [ 10121 ] |
Modified by: @cincuranetFix Version: 2.1.0 [ 10102 ] => |
Commented by: @carlosga delayed for now to be fixed in 2.5 |
Modified by: @carlosgaFix Version: 2.5.0 [ 10170 ] |
Commented by: Daniel Junges (djunges) wo are working with .net provider 2.1.0 and firebird 2.0.3. it's very strange because we have only two clients that receives this error message, and i don't know how to reproduce it on our office bacause it do not rises here for us. We are not using transactions on this software; this error occurs since we have updated to .NET 3.5 Here are the Exception: FirebirdSql.Data.FirebirdClient.FbException: invalid transaction handle (expecting explicit transaction start) ---> FirebirdSql.Data.Common.IscException: Exception of type 'FirebirdSql.Data.Common.IscException' was thrown. regards |
Modified by: @cincuranetassignee: Carlos Guzman Alvarez [ carlosga_fb ] => Jiri Cincura [ cincura_net ] |
Modified by: @cincuranetFix Version: 2.5.0 [ 10170 ] => |
Modified by: @cincuranetstatus: In Progress [ 3 ] => Open [ 1 ] |
Commented by: Ralf Giese (rgiese) To fix issue you can change code in FbCommandBuilder.cs (SVN Rev. 666) as follows. 1. Add field in FbCommand class private bool isAdded; 2. Add line to save state if command is added to list of prepared commands.
3. Modify Release() method to prevent calling code on InnerConnection after old code:
new code:
If connection is closing it releases this command und removes it from list. There didn't appear any errors in Demo test case application after provider was modifided. |
Commented by: @cincuranet r.717 |
Modified by: @cincuranetstatus: Open [ 1 ] => Resolved [ 5 ] resolution: Fixed [ 1 ] Fix Version: 2.5.0 Alpha 3 [ 10261 ] Fix Version: 2.5.0 [ 10170 ] |
Commented by: Ralf Giese (rgiese) Fix in rev. 717 simplifies the code changes decribes in my previous comment. |
Commented by: @cincuranet OK, I see the point. I'll re-fix it this week. |
Commented by: @cincuranet r.731 |
Commented by: Ralf Giese (rgiese) Fix in rev. 731 isn't correct yet. line 794 if (!this.addedToPrepared) must be changed to if (this.addedToPrepared) |
Commented by: @cincuranet Ups, rest from previous fix. Committed fixed. |
Modified by: @cincuranetFix Version: 2.5.0 [ 10170 ] => |
Submitted by: Ralf Giese (rgiese)
Attachments:
Demo.cs
We've developed a client-server application using .NET Data Provider
1.6.3 in the data layer of the server. Each client has a separate
data access object on the server and is calling it via .NET Remoting.
The application worked fine in a production environment with about 12
clients for several month's. Then I updated the data provider to v2.0.
After a timespan from some hours to some days one of the data access
objects began to return IscExceptions, mostly "invalid transaction
handle (expecting explicit transaction start)", on almost all following
calls until the server was restarted. No changes with implementing
data provider v1.7.1, so I had to go back to v1.6.3.
I built a test environment and tried to reproduce and debug the error.
Each data access object of my application contains a common
FbConnection object and some FbDataAdapters with FbCommands for
multiple use. There are procedures using temporary FbCommands too,
e. g. each call creates a new FbCommannd object with the common
connection object. There's no explicit Dispose() for those commands,
so disposing should be done by garbage collector later. At the end of
each call to the data access object the common connection will be
closed for further use in the connection pool.
In normal operation state FbConnection.Close() releases all prepared
commands and removes them from inner connection. I found, that in error
state FbConnection.PreparedCommands doesn't contain the FbCommand
object that rises the exception during FbCommand.Execute(). So this
command isn't released and if it is used again subsequent it has still
an (unvalid) prepared GdsStatement. The GdsDatabase of this statement
meanwhile can point to an inner connection of the connection pool that
is closed or used by another thread. Calling GdsStatement.Execute() on
such an unvalid statement rises an IscError.
But why PreparedCommands dosn't contains the command when closing
connection? When garbage collector disposes an FbCommand object with an
open FbConnection object, it calls
FbConnectionInternal.RemovePreparedCommand() in FbCommand.Release().
In RemovePreparedCommand() the garbage collection thread calls
PreparedCommands (get) and can cause a conflict with an application
thread there. Sometimes the application thread creates a new ArrayList
for prepared commands and adds the first command. After that the
garbage collection thread creates a new empty ArrayList and replaces
the ArrayList with the new command.
I checked csv for .Net Data Provider v1.6.3. There's a
GC.SuppressFinalize() in the constructor of the FbCommand class.
Therefore no errors occur in that version.
I added a explicit Dispose() to each temporary FbCommand and no further
errors occured. Is this the recommended way to use FbCommand? I think
it would be useful to modify the provider to prevent that garbage
collection threat can reach code that is still executed by application
threads.
A simple test application is attached. The number of required cycles to
get the first error vary depending from used machine. On WinXP-SP2
workstation with Pentium 4 HT 3.2 GHz I needed up to about 50000 cycles
(2 hours). On a second machine with Pentium 4 2.2 GHz (without hyper
threading!) I got first error after about 150 cycles (40 seconds) yet.
To gain the effect on the first mentioned machine I temporary modified
FbConnectionInternal:
-----
// next line for test only
Random delayRadom = new Random();
public ArrayList PreparedCommands
{
get
{
if (this.preparedCommands == null)
{
// next 2 lines for test only
int delay = delayRadom.Next(2);
System.Threading.Thread.Sleep(delay);
}
-----
With this changes error occured on first machine after about 50 cycles.
Commits: 0ca5628 0c0eb2c
The text was updated successfully, but these errors were encountered: