[ 
https://issues.apache.org/jira/browse/OPENJPA-825?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12656365#action_12656365
 ] 

Pinaki Poddar commented on OPENJPA-825:
---------------------------------------

Multithreaded mode of OpenJPA kernel and parallel database operation in Slice
===============================================================

Background
   a) OpenJPA allows multiple threads to execute a single instance of 
EntityManager. By default, OpenJPA assumes that a single thread is invoking 
operations on a particular instance of EntityManager. 
   openjpa.Multithreaded configuration property can be set to true to signal 
multithreaded acceess. Under multithreaded mode, OpenJPA kernel classes acquire 
an instance-level Reentrant lock before almost any of its methods and 
   releases the lock on the method's finally block.

   b) Slice executes most of the frequent database operations (query, flush) on 
individual slice in separate threads.


   These two threading models conflict and give rise to a classic deadlock 
scenario as follows:

   1. Assume EntityManager instance em, a Query instance Q created by E, 
openjpa.Multithreaded=true, a user thread UT and three slices S1,S2,S3

   2. T calls em.x() or Q.y()

   3. em/Q acquires a reentrant lock L on thread UT and invokes lower-layer 
method which eventually invokes Slice operations

   4. Slice spawns three threads ST1, ST2, ST3 and on each of these threads 
invoke identical operation S.z()

   5. If S.z() on ST1 invokes any operation of em/Q then ST1 can not acquire L 
as it is acquired by em/Q in step 3 and yet to be released. The architecture of 
Slice makes it typical that S.z() invokes one or more method on em or Q. 

   6. em.x()/Q.y() can not release L till  S.z() finishes   

   7. S.z() can not finish because ST1 waits for L to be released by UT



Observations
==========
  a) openjpa.Multithreaded is a non-default option and single threaded 
operation on em is more prevalent. Note that single threaded access does not 
imply that em can only be invoked only on UT. It is perfectly permissible to 
start a transaction of em on some thread UT, commit the transaction and then 
start another transaction on same em on a different thread UT2 under default 
mode of openjpa.Multithreaded=false.

  b) Execution of common database operations on each slice S1, S2,... in 
parallel has definite performance benefit and should be the default choice. And 
this is at par with the default choice of openjpa.Multithreaded=false


Possible solutions
===============
  1. Under openjpa.Multithreaded=true, execute database operation on all slices 
on the same user thread UT. Otherwise, execute database operation on each slice 
on separate thread
  2. Modify OpenJPA kernel's threading model to make it more fine-grained, 
read/write sensitive
  3. Detect deadlock and throw exception as ST1 waits on L
  
My preferred solution is (1). 

> slices: hangs with multithreaded true
> -------------------------------------
>
>                 Key: OPENJPA-825
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-825
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>    Affects Versions: 2.0.0
>            Reporter: Fernando
>            Assignee: Pinaki Poddar
>            Priority: Critical
>         Attachments: hang-multithread.jstack, hang-multithread.txt
>
>
> When I turned on openjpa.Multithreaded as a possible fix for another bug, I 
> see that the system hangs.  Attached are going to be a log file, and jstack, 
> showing how it system hung on the very first query. ( it did execute a few 
> find() operations, but those are not executed via ParallelExecutor ).

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to