Bug #21446 | Stale data read by pooled database connection | ||
---|---|---|---|
Submitted: | 4 Aug 2006 13:05 | Modified: | 23 Sep 2006 14:13 |
Reporter: | Phil Haigh | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | Connector / J | Severity: | S2 (Serious) |
Version: | 4.1.13 | OS: | Linux (Debian Linux) |
Assigned to: | CPU Architecture: | Any |
[4 Aug 2006 13:05]
Phil Haigh
[4 Aug 2006 13:38]
Mark Matthews
> So it would appear that on occasion the JDBC driver is returning stale data from > a read. No, because it can't. It doesn't cache row data. > - Under what circumstances can this occurr? Are you sure you're not missing a commit() somewhere in your application, maybe due to some alternate code path being taken the 1% of the times this seems to happen? This sounds an awful lot like when developers get confused about the semantics of REPEATABLE_READ which is the default isolation level used by MySQL when using InnoDB tables. (i.e. a connection has started a transaction, and has never committed or rolled-back, and then is used later to try and "see" new data, but is actually working on the "old" snapshot that was created when the transaction was actually started). > - Are there any known software bugs or environment issues that sound related to > this issue? No. Every time this has been brought up before it is due to the reasons stated above.
[4 Aug 2006 15:26]
Phil Haigh
I'm positive that a commit occurs. I've already instrumented the code heavily using java.util.logging to demonstrate what is happening - including whether a commit takes place. It does. Further, in addition to the changes on the 'main' table, an audit log is written. I have found during my investigations that the audit log is always written, even when the update fails. The log trace shows that the correct (modified) data is passed to the JDBC update and then successfully re-read from the database using a PreparedStatement on the same connection, it is the later read that fails. This is the only table in the application that features frequent read/update/read activity, and it is the only area of the application exhibiting this behaviour - and all parts of the application use a common set of persistence management code. I would expect you to be sceptical but I'm not your typical JDBC or J2EE newbie, I've been developing J2EE applications for six years and worked professionally with databases in C, Cobol, Fortran for over ten years before Java came along. My application code is pretty bullet-proof as far as connection pool leakage goes but just in case (because I've been investigating this for some time and wanted to remove all doubt) you'll see I'm using eviction to recover leaking connections. If there were leaking connections the entire transaction would roll back, and that is not what I am seeing anyway.
[4 Aug 2006 15:28]
Phil Haigh
Having just re-read my last comment I'd like to clarify it. The audit log is another table.
[17 Aug 2006 9:57]
Georg Portwich
Hi, I have seen a similar behaviour also together with tomcat5.5 and mysql. Under some circumstances the connection will display stale data from the connection In detail: you read data with connection A. After this you will update this data with connection B. Now you read the data again with connection A. You will not see the changes done with connection B that is still open. This happens independent from the transaction status. If you close connection B, you will see the changes. You can test this if you modify the data with a different application – for example some mysql tools. This is just a working theory. If could verify this or have a solution for the problem please let me know. The main problem is – you don’t see the problem with tomcat5.0. So some already running applications may have problems to update to tomcat5.5
[27 Aug 2006 14:48]
Phil Haigh
Further update on my problem. I have been using an o/R mapping library to manage persistence. Two weeks ago I hand-crafted JDBC in the DAO code for this table and despite completely replacing the original code, the problem remains. I have logs that show the right data being passed into the persistence layer and bound to the JDBC update; I have logs showing the data re-read correctly and then later, a minute or so for example, re-read again with some changes missing. So I am still convinced that the problem is not of my making. I'm about to change hosts and so I will hold off further postings until I have the site up and running on the new host.
[28 Aug 2006 8:38]
Georg Portwich
Hi, I solved our problem. The persistence layer of the application we use does not support transaction – the commit after all updates were missing. But in the standard configuration transactions are enabled. All connection we get from a pool. If we got a connection with an open transaction we see the data from the current transaction. If we get any other connection we see the data from the database (and not the updated data). If we are running under a normal load only one connection from the pool is used and the application is running perfectly fine. Only in very rare situation we see the strange behaviour. Maybe you have a similar problem in your persistence layer. Georg
[23 Sep 2006 10:29]
Valeriy Kravchuk
It is not a bug in a MySQL's code. It is a problem of application(s) used.
[23 Sep 2006 14:13]
Phil Haigh
I have solved my problem too... by moving hosting company. Shocking but true, nameonthe.net have a buggy infrastructure or MySQL build because as soon as I moved to weconexion.net the problem vanished. Same pooling and JDBC jars, and the same Tomcat and database version. I was seeing a lot of connection timeouts on my old host, they have also vanished... At least I wasn't going insane, even if it wasn't a bug that can be attributed to you guys. keep up the excellent work.