Issue Details (XML | Word | Printable)

Key: JDBC-300
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Mark Rotteveel
Reporter: Stefan Schmaltz
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Jaybird JCA/JDBC Driver

Synchronization Bug with Blob - SOLUTION

Created: 19/Feb/13 02:35 PM   Updated: 11/May/13 03:13 PM
Component/s: JDBC driver, Services API, Wire protocol
Affects Version/s: Jaybird 2.1.6, Jaybird 2.2, Jaybird 2.2.1, Jaybird 2.2.2, Jaybird 2.2.3, Jaybird 3.0
Fix Version/s: Jaybird 2.2.3

Time Tracking:
Not Specified

Environment: All java


 Description  « Hide
In our multi-threaded application we got errors like this:
java.lang.ArrayIndexOutOfBoundsException
Error executing sql instruction:

select * from ORDERINGS ons join USERS usr on usr.USR_ID = ons.ONS_USR_ID join ONSSUPPLIERS oss on oss.OSS_ONS_ID = ons.ONS_ID left join ADDRESSDATA ada on ada.ADA_ID = oss.OSS_ADA_ID left join SUPPL
IER sup on sup.SUP_ID = oss.OSS_SUP_ID left join ADRCONTACTPERSON acp on acp.acp_id = oss.OSS_ACP_ID where ONS_TYPE=3 AND ONS_STATE=18 AND (ons.ONS_DELIVERYDATEGIV is not NULL or ons.ONS_DELIVERYDATER
EQ is not NULL )
java.lang.reflect.UndeclaredThrowableException
at org.firebirdsql.jdbc.FBStatementFactory.createPreparedStatement(FBStatementFactory.java:101)
at org.firebirdsql.jdbc.AbstractConnection.prepareStatement(AbstractConnection.java:1187)
at org.firebirdsql.jdbc.AbstractConnection.prepareStatement(AbstractConnection.java:942)
at com.borland.dx.sql.dataset.Database.createPreparedStatement(Database.java:923)
at komet3.DB.Komet3Database.createPreparedStatement(Komet3Database.java:210)
at komet3.DB.entityTools.Komet3EntityProxy.loadDetailData(Komet3EntityProxy.java:905)
at komet3.DB.entityTools.Komet3EntityProxy.invoke(Komet3EntityProxy.java:582)
at komet3.DB.entities.UserGroup_$$_javassist_2.getUserGroupStartPages(UserGroup_$$_javassist_2.java)
at komet3.client.apps.start.Komet3Start.updateBrowsers(Komet3Start.java:60)
at komet3.client.apps.start.Komet3Start.<init>(Komet3Start.java:44)
at komet3.client.apps.start.Komet3Start_func.runK3(Komet3Start_func.java:74)
at komet3.client.Komet3ClientAppMainFrame.resetDesktop(Komet3ClientAppMainFrame.java:960)
at komet3.client.Komet3ClientAppMainFrame.initDesktop(Komet3ClientAppMainFrame.java:878)
at komet3.client.Komet3ClientAppMainFrame.<init>(Komet3ClientAppMainFrame.java:722)
at komet3.client.Komet3ClientApp.<init>(Komet3ClientApp.java:101)
at komet3.client.Komet3ClientApp$1.run(Komet3ClientApp.java:245)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:688)
at java.awt.EventQueue$3.run(EventQueue.java:686)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:697)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Caused by: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at org.firebirdsql.gds.impl.wire.AbstractJavaGDSImpl.parseTruncSqlInfo(AbstractJavaGDSImpl.java:2455)
at org.firebirdsql.gds.impl.wire.AbstractJavaGDSImpl.parseSqlInfo(AbstractJavaGDSImpl.java:2410)
at org.firebirdsql.gds.impl.wire.AbstractJavaGDSImpl.iscDsqlPrepare(AbstractJavaGDSImpl.java:1552)
at org.firebirdsql.gds.impl.GDSHelper.prepareStatement(GDSHelper.java:190)
at org.firebirdsql.jdbc.AbstractStatement.prepareFixedStatement(AbstractStatement.java:1440)
at org.firebirdsql.jdbc.AbstractPreparedStatement.prepareFixedStatement(AbstractPreparedStatement.java:1281)
at org.firebirdsql.jdbc.AbstractPreparedStatement.<init>(AbstractPreparedStatement.java:137)
at org.firebirdsql.jdbc.FBPreparedStatement.<init>(FBPreparedStatement.java:45)
at sun.reflect.GeneratedConstructorAccessor15.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.firebirdsql.jdbc.FBStatementFactory.createPreparedStatement(FBStatementFactory.java:89)
at org.firebirdsql.jdbc.AbstractConnection.prepareStatement(AbstractConnection.java:1187)
at org.firebirdsql.jdbc.AbstractConnection.prepareStatement(AbstractConnection.java:942)
at com.borland.dx.sql.dataset.Database.createPreparedStatement(Database.java:923)
at komet3.DB.Komet3Database.createPreparedStatement(Komet3Database.java:210)
at komet3.DB.entityTools.Komet3EntityProxy.loadDetailData(Komet3EntityProxy.java:905)
at komet3.DB.entityTools.Komet3EntityProxy.invoke(Komet3EntityProxy.java:582)
at komet3.DB.entities.UserGroup_$$_javassist_2.getUserGroupStartPages(UserGroup_$$_javassist_2.java)
at komet3.client.apps.start.Komet3Start.updateBrowsers(Komet3Start.java:60)
at komet3.client.apps.start.Komet3Start.<init>(Komet3Start.java:44)
at komet3.client.apps.start.Komet3Start_func.runK3(Komet3Start_func.java:74)
at komet3.client.Komet3ClientAppMainFrame.resetDesktop(Komet3ClientAppMainFrame.java:960)
at komet3.client.Komet3ClientAppMainFrame.initDesktop(Komet3ClientAppMainFrame.java:878)
at komet3.client.Komet3ClientAppMainFrame.<init>(Komet3ClientAppMainFrame.java:722)
at komet3.client.Komet3ClientApp.<init>(Komet3ClientApp.java:101)
at komet3.client.Komet3ClientApp$1.run(Komet3ClientApp.java:245)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:688)
at java.awt.EventQueue$3.run(EventQueue.java:686)


"Caused by: java.lang.OutOfMemoryError: Requested array size exceeds VM limit"
Also many
"Negative Index" Exception
and
"Array Index out of Bounce" Exceptions

Looks like the problem happens while executing many sql instructions in threads with reading blob data.
And this is the reason: AbstractJavaGDSImpl.iscBlobInfo is not synchronized to db, only to blob

same thing with iscSeekBlob and fbCancelOperation

SOLUTION:
add synchronization to those 3 methods:

instead of
    synchronized (blob) {
...

use this:

    synchronized (blob) {
      synchronized (db) {
        try {
....

Then all those Exception are gone!


 All   Comments   Work Log   Change History   Version Control   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Mark Rotteveel added a comment - 21/Feb/13 08:06 PM - edited
The issue was already fixed in 2.3 during a cleanup of the wire protocol code. I committed the fix for 2.2.3. I will need to do some additional testing as I also fixed some of the synchronisation in the JNI implementation (also in 2.3).

Be aware though that JDBC does not actually require thread-safety (although Jaybird - usually - does provide it), and it is recommended that a single JDBC connection only be used on a single thread at a time; interleaving requests from multiple threads to the same connection is - in general - not recommended. You might want to check if you are sharing a single connection with multiple threads: I'd advise to change it so this doesn't happen.