Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [eclipselink-users] session handling for multi-threaded fat client

I see, you are using batch writing, and the background thread is trying to
flush the other threads batch.  I suppose this is why it is best to use a
ServerSession.

If you called beginTransaction() and commitTransaction() around each query
from your background thread, this should remove this issue.  But still
better to use a ServerSession.



Anthony Oganesian wrote:
> 
> James,
> 
> In the stack trace below you can see how 2 threads work in parallel. 
> I put a "U" at the start of the line for UI lines and "B" for 
> background lines.
> 
> I can consistently reproduce this by setting the frequency of 
> my background thread to 0.5 second and just putting a simple 
> ReadAllQuery in a loop in the main UI thread. I tested both solutions: 
> my SynchronizedSession and ServerSession with one connection (per your 
> recommendation). Both perform well under this kind of stress test. 
> The only drawback to using the ServerSession/ClientSession that I can see 
> is that I loose session.writeObject(), session.insertObject() convenience 
> methods which are sometimes used in my legacy code which I am reluctant to 
> refactor at the moment.
> 
> - The exception appears in the EL code. Something to do with the batching?
> - I am using JTDS driver for MS SQL database
> 
> Thank you very much!
> --
> Tony
> 
> 
> U[EL Finest]: 2009.02.12
> 12:21:03.173--DatabaseSessionImpl(1553074)--Thread(Thread[main,5,main])--Exe
> cute query
> ReadAllQuery(com.ligolab.application.domain.diagnosis.DiagnosisGroup)
> B[EL Finer]: 2009.02.12
> 12:21:03.174--DatabaseSessionImpl(1553074)--Connection(19220932)--Thread(Thr
> ead[main,5,main])--Begin batch statements
> B[EL Fine]: 2009.02.12
> 12:21:03.174--DatabaseSessionImpl(1553074)--Connection(19220932)--Thread(Thr
> ead[main,5,main])--UPDATE SECURITY_APPLICATION_STATUS SET
> LAST_HEARTBEAT_TIME = {ts '2009-02-12 B12:22:14.303'} WHERE
> ((APPLICATION_ID
> = 0) AND (WORKSTATION_ID = 96))
> B[EL Finer]: 2009.02.12
> 12:21:03.174--DatabaseSessionImpl(1553074)--Connection(19220932)--Thread(Thr
> ead[main,5,main])--End Batch Statements
> B[EL Finer]: 2009.02.12
> 12:21:03.200--DatabaseSessionImpl(1553074)--Connection(19220932)--Thread(Thr
> ead[Application Management Thread,1,main])--commit transaction
> B[EL Finer]: 2009.02.12
> 12:21:03.287--UnitOfWork(11369856)--Thread(Thread[Application Management
> Thread,1,main])--end unit of work commit
> B[EL Finer]: 2009.02.12
> 12:21:03.287--UnitOfWork(11369856)--Thread(Thread[Application Management
> Thread,1,main])--release unit of work
> U[EL Warning]: 2009.02.12
> 12:21:03.287--DatabaseSessionImpl(1553074)--Thread(Thread[main,5,main])--jav
> a.util.ConcurrentModificationException
> 	at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
> 	at java.util.AbstractList$Itr.next(Unknown Source)
> 	at
> org.eclipse.persistence.internal.databaseaccess.DynamicSQLBatchWritingMechan
> ism.prepareJDK12BatchStatement(DynamicSQLBatchWritingMechanism.java:206)
> 	at
> org.eclipse.persistence.internal.databaseaccess.DynamicSQLBatchWritingMechan
> ism.executeBatchedStatements(DynamicSQLBatchWritingMechanism.java:123)
> 	at
> org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecut
> eCall(DatabaseAccessor.java:539)
> 	at
> org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall
> (DatabaseAccessor.java:500)
> 	at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeCall(Abstra
> ctSession.java:855)
> 	at
> org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.execut
> eCall(DatasourceCallQueryMechanism.java:204)
> 	at
> org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.execut
> eCall(DatasourceCallQueryMechanism.java:190)
> 	at
> org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.execut
> eSelectCall(DatasourceCallQueryMechanism.java:261)
> 	at
> org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.select
> AllRows(DatasourceCallQueryMechanism.java:594)
> 	at
> org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllR
> owsFromTable(ExpressionQueryMechanism.java:2506)
> 	at
> org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllR
> ows(ExpressionQueryMechanism.java:2464)
> 	at
> org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(Rea
> dAllQuery.java:478)
> 	at
> org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(Ob
> jectLevelReadQuery.java:879)
> 	at
> org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:666
> )
> 	at
> org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelRead
> Query.java:840)
> 	at
> org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:456)
> 	at
> org.eclipse.persistence.internal.sessions.AbstractSession.internalExecuteQue
> ry(AbstractSession.java:2207)
> 	at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(Abstr
> actSession.java:1178)
> 	at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(Abstr
> actSession.java:1162)
> 	at
> org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(Abstr
> actSession.java:1108)
> 	at
> org.eclipse.persistence.internal.sessions.AbstractSession.readAllObjects(Abs
> tractSession.java:2494)
> 	at
> com.ligolab.application.ligolab.main.LigoLabInitializer.initApplicationEntit
> iesFromDB(LigoLabInitializer.java:145)
> 
> 
> -----Original Message-----
> From: eclipselink-users-bounces@xxxxxxxxxxx
> [mailto:eclipselink-users-bounces@xxxxxxxxxxx] On Behalf Of James
> Sutherland
> Sent: Wednesday, February 18, 2009 05:25
> To: eclipselink-users@xxxxxxxxxxx
> Subject: RE: [eclipselink-users] session handling for multi-threaded fat
> client
> 
> 
> If each thread has its own UnitOfWork to isolate its changes then you
> should
> be ok.  The database commit is already synchronized through the
> DatabaseSession's transaction mutex, so you should not need to do anything
> special.  Even without the UnitOfWork I can't see how you could have got a
> ConcurrentModificationException, please include the stack trace for this,
> was it in EclipseLink code, your JDBC driver or your application code?
> 
> The main benefit of using the ServerSession over the DatabaseSession is
> that
> the JDBC connections are used exclusively, where as the DatabaseSession
> will
> allow concurrent reads on the same JDBC connection (but not concurrent
> writes), depending on your JDBC driver it may not allow concurrent reads
> on
> the same connection.  You could use an external connection pool with a
> DatabaseSession to prevent concurrent reads.
> 
> 
> 
> Anthony Oganesian wrote:
>> 
>> James,
>> 
>> Thank you very much for looking into this! 
>> 
>> My background thread is reading and writing to the DB, but is using a
>> completely separate set of tables. 
>> But in theory let's say that was not the case. All my DB updates are
>> handled
>> through a UnitOfWork, 
>> is that not sufficient to protect threads from committing/rolling back
>> each
>> others changes?
>> I am curious because one other suggestion I got from a forum was to do
>> all
>> my reads and writes through a 
>> UnitOfWork to allow multiple threads to work with the same
>> DatabaseSession. 
>> 
>> In my stress test it seems that my home-brewed synchronization works for
>> me,
>> but the single-connection
>> ServerSession seems a more proper way of accomplishing the same thing,
>> and
>> yes I am OK with one thread waiting 
>> For the other to finish. (my background thread is a very low-volume once
>> every 15 minute operation)
>> 
>> Also, there was a mistake in my original post:
>> synchronized(SynchronizedSession.this) is needed to 
>> Synchronize UnitOfWork commits with session's synchronized methods.
>> 
>>> public void commit() throws DatabaseException, OptimisticLockException
>>> {
>>> 	synchronized(SynchronizedSession.this)
>>>     {
>>>      super.commit();    
>>>     }
>>>}
>> 
>> --
>> Tony
>> 
>> 
> 
> 
> _______________________________________________
> eclipselink-users mailing list
> eclipselink-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
> 
> 


-----
---
http://wiki.eclipse.org/User:James.sutherland.oracle.com James Sutherland 
http://www.eclipse.org/eclipselink/
 EclipseLink ,  http://www.oracle.com/technology/products/ias/toplink/
TopLink 
Wiki:  http://wiki.eclipse.org/EclipseLink EclipseLink , 
http://wiki.oracle.com/page/TopLink TopLink 
Forums:  http://forums.oracle.com/forums/forum.jspa?forumID=48 TopLink , 
http://www.nabble.com/EclipseLink-f26430.html EclipseLink 
Book:  http://en.wikibooks.org/wiki/Java_Persistence Java Persistence 
-- 
View this message in context: http://www.nabble.com/session-handling-for-multi-threaded-fat-client-tp22031861p22160864.html
Sent from the EclipseLink - Users mailing list archive at Nabble.com.



Back to the top