[
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.