[ 
https://issues.apache.org/jira/browse/DERBY-4129?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Knut Anders Hatlen updated DERBY-4129:
--------------------------------------

    Attachment: BlobDeadlock.java
                threaddump.txt

I am able to reproduce this deadlock. See the attached files BlobDeadlock.java 
and threaddump.txt.

Note that the repro has two threads performing queries using the same 
Connection object. As far as I can see, that's the only way two threads can end 
up accessing the same BaseContainerHandle, and thereby running into this 
deadlock. Having concurrent threads using the same Connection object is not 
recommended, but it should of course not cause a Java-level deadlock.

Normally, deadlock between threads sharing the same Connection is prevented by 
only allowing one thread at a time to enter the engine through a single 
Connection. For instance, EmbedResultSet.next() and EmbedResultSet.close() will 
synchronize on the parent EmbedConnection object before calling the engine 
code. The getters don't synchronize on the EmbedConnection because they just 
return a value that was cached in the ResultSet when next() was called.

The reason why this doesn't work as intended in this case, is that 
EmbedResultSet.getBytes() will have to go to the store to fetch the value if 
the BLOB column is larger than what EmbedResultSet.next() will cache 
(basically, it doesn't fit on one page). But since the getters don't 
synchronize on the EmbedConnection, we now enter the engine without making sure 
that no other thread is actively using the same connection. If getBytes() had 
synchronized on the connection, we would have been stopped from entering the 
engine much earlier because the other thread involved in the deadlock enters 
the engine from close(), where it does synchronize on the connection, and we 
wouldn't run into the deadlock.

> Deadlock
> --------
>
>                 Key: DERBY-4129
>                 URL: https://issues.apache.org/jira/browse/DERBY-4129
>             Project: Derby
>          Issue Type: Bug
>    Affects Versions: 10.4.2.0
>         Environment: Linux 2.6.18-53.1.14.el5 #1 SMP Wed Mar 5 11:36:49 EST 
> 2008 i686 i686 i386 GNU/Linux
>            Reporter: Malchenko Inna
>         Attachments: BlobDeadlock.java, threaddump.txt
>
>
> Threads working with embedded derby get deadlocked.
> Thread dump:
> Found one Java-level deadlock:
> =============================
> "http-8080-13":
>   waiting to lock monitor 0x09d1a37c (object 0x9560fcd8, a 
> org.apache.derby.impl.store.raw.data.BaseContainerHandle),
>   which is held by "dwc.ma.MAJobsManager:dwc.ma.MAManager"
> "dwc.ma.MAJobsManager:dwc.ma.MAManager":
>   waiting to lock monitor 0x09d1a57c (object 0x93da0180, a 
> org.apache.derby.impl.store.raw.data.StoredPage),
>   which is held by "http-8080-13"
> Java stack information for the threads listed above:
> ===================================================
> "http-8080-13":
>       at java.util.Observable.deleteObserver(Observable.java:78)
>       - waiting to lock <0x9560fcd8> (a 
> org.apache.derby.impl.store.raw.data.BaseContainerHandle)
>       at 
> org.apache.derby.impl.store.raw.data.BasePage.releaseExclusive(Unknown Source)
>       - locked <0x93da0180> (a 
> org.apache.derby.impl.store.raw.data.StoredPage)
>       at 
> org.apache.derby.impl.store.raw.data.CachedPage.releaseExclusive(Unknown 
> Source)
>       at 
> org.apache.derby.impl.store.raw.data.StoredPage.releaseExclusive(Unknown 
> Source)
>       at org.apache.derby.impl.store.raw.data.BasePage.unlatch(Unknown Source)
>       at 
> org.apache.derby.impl.store.raw.data.OverflowInputStream.fillByteHolder(Unknown
>  Source)
>       at 
> org.apache.derby.impl.store.raw.data.BufferedByteHolderInputStream.read(Unknown
>  Source)
>       at java.io.DataInputStream.readFully(DataInputStream.java:176)
>       at java.io.DataInputStream.readFully(DataInputStream.java:152)
>       at org.apache.derby.iapi.types.SQLBinary.readExternal(Unknown Source)
>       at org.apache.derby.iapi.types.SQLBinary.getValue(Unknown Source)
>       at org.apache.derby.iapi.types.SQLBinary.getBytes(Unknown Source)
>       at org.apache.derby.impl.jdbc.EmbedResultSet.getBytes(Unknown Source)
>       at dwc.ma.MAOrderProcessor.loadData(MAOrderProcessor.java:147)
>       - locked <0x91f211b0> (a java.lang.Object)
>       - locked <0x91f6a068> (a dwc.ma.MAOrderProcessor)
>       at 
> dwc.ma.MAOrderProcessor.generateBundlesForUser(MAOrderProcessor.java:538)
>       - locked <0x91f6a068> (a dwc.ma.MAOrderProcessor)
>       at 
> dwc.ma.MARequestProcessor$HBundleRequest.process(MARequestProcessor.java:239)
>       at dwc.ma.MARequestProcessor.processRequest(MARequestProcessor.java:39)
>       at dwc.ma.doProc.doPost(doProc.java:92)
>       at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
>       at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
>       at 
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
>       at 
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
>       at 
> org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:738)
>       at 
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
>       at 
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
>       at 
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
>       at 
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
>       at 
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
>       at 
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
>       at 
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
>       at 
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
>       at 
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
>       at 
> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
>       at 
> org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
>       at java.lang.Thread.run(Thread.java:595)
> "dwc.ma.MAJobsManager:dwc.ma.MAManager":
>       at 
> org.apache.derby.impl.store.raw.data.BasePage.releaseExclusive(Unknown Source)
>       - waiting to lock <0x93da0180> (a 
> org.apache.derby.impl.store.raw.data.StoredPage)
>       at 
> org.apache.derby.impl.store.raw.data.CachedPage.releaseExclusive(Unknown 
> Source)
>       at 
> org.apache.derby.impl.store.raw.data.StoredPage.releaseExclusive(Unknown 
> Source)
>       at org.apache.derby.impl.store.raw.data.BasePage.update(Unknown Source)
>       at java.util.Observable.notifyObservers(Observable.java:142)
>       at java.util.Observable.notifyObservers(Observable.java:98)
>       at 
> org.apache.derby.impl.store.raw.data.BaseContainerHandle.informObservers(Unknown
>  Source)
>       at 
> org.apache.derby.impl.store.raw.data.BaseContainerHandle.close(Unknown Source)
>       - locked <0x9560fcd8> (a 
> org.apache.derby.impl.store.raw.data.BaseContainerHandle)
>       at 
> org.apache.derby.impl.store.access.conglomerate.OpenConglomerate.close(Unknown
>  Source)
>       at 
> org.apache.derby.impl.store.access.conglomerate.GenericController.close(Unknown
>  Source)
>       at 
> org.apache.derby.impl.store.access.conglomerate.GenericConglomerateController.closeForEndTransaction(Unknown
>  Source)
>       at 
> org.apache.derby.impl.store.access.RAMTransaction.closeControllers(Unknown 
> Source)
>       at org.apache.derby.impl.store.access.RAMTransaction.commit(Unknown 
> Source)
>       at 
> org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.doCommit(Unknown
>  Source)
>       at 
> org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.userCommit(Unknown
>  Source)
>       at org.apache.derby.impl.jdbc.TransactionResourceImpl.commit(Unknown 
> Source)
>       at 
> org.apache.derby.impl.jdbc.EmbedConnection.commitIfAutoCommit(Unknown Source)
>       at 
> org.apache.derby.impl.jdbc.ConnectionChild.commitIfAutoCommit(Unknown Source)
>       at org.apache.derby.impl.jdbc.EmbedStatement.resultSetClosing(Unknown 
> Source)
>       at org.apache.derby.impl.jdbc.EmbedResultSet.close(Unknown Source)
>       - locked <0x91f0b7d0> (a org.apache.derby.impl.jdbc.EmbedConnection30)
>       at 
> dwc.ma.MAStatsProcessor$UserStatsBundlesProc.run(MAStatsProcessor.java:117)
>       at dwc.ma.MAJobsManager$Runner.run(MAJobsManager.java:84)
>       - locked <0x91fce338> (a java.util.LinkedList)
>       at java.lang.Thread.run(Thread.java:595)
> Found 1 deadlock.

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