[ 
https://issues.apache.org/jira/browse/DERBY-3757?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12615950#action_12615950
 ] 

Knut Anders Hatlen commented on DERBY-3757:
-------------------------------------------

It looks to me as if the rest of the class actually uses synchronization on 
"this" when entries are added to or removed from the  hash table. The exception 
is if it happens during recovery (which is single-threaded and therefore OK), 
but it also looks like there's a code path from Xact.close() -> 
XactFactory.remove() -> Xact.remove() -> Hashtable.remove() that is not 
synchronized on "this" and which is likely causing the assert failure by 
removing an entry while another thread is iterating over the table.

Although this failure is seen in debug code, I think it indicates that the 
synchronization scheme used in TransactionTable is flawed, so I would feel more 
comfortable if we fixed the synchronization. I have tried to understand how the 
synchronization in this class is supposed to work before, but with no success.

What I have problem understanding, is when to synchronize on which object. The 
class javadoc says that the class depends on Hashtable synchronization, but 
says nothing about synchronization on "this". Some of the methods explicitly 
synchronize on "this", others on "trans", some rely on the implicit 
synchronization from the Hashtable class, and some have a synchronized (this) 
block enclosing a synchronized (trans) block. Some of the code even says that 
we need synchronization on "this" here without synchronizing on "this".

> 'ASSERT FAILED transaction table has null entry when running new 
> StressMultiTest
> --------------------------------------------------------------------------------
>
>                 Key: DERBY-3757
>                 URL: https://issues.apache.org/jira/browse/DERBY-3757
>             Project: Derby
>          Issue Type: Bug
>          Components: Store
>    Affects Versions: 10.5.0.0
>         Environment: Windows XP
> java version "1.5.0"
> Java(TM) 2 Runtime Environment, Standard Edition (build pwi32dev-20070201 
> (SR4))
> IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Windows XP x86-32 
> j9vmwi3223-20070201 (JIT enabled)
> J9VM - 20070131_11312_lHdSMR
> JIT  - 20070109_1805ifx1_r8
> GC   - 200701_09)
> JCL  - 20070131
>            Reporter: Kathey Marsden
>
> When trying the DERBY-1764-V2.diff patch of DERBY-1764, I got this assertion 
> running the test. It appears to be a bug iin Derby.
> 1) 
> testStressMulti(org.apache.derbyTesting.functionTests.tests.multi.StressMultiTest)java.sql.SQLException:
>  Java exception: 'ASSERT FAILED transaction table has null entry: 
> org.apache.derby.shared.common.sanity.AssertFailure'.
>         at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:45)
>         at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Util.java:87)
>         at org.apache.derby.impl.jdbc.Util.javaException(Util.java:244)
>         at 
> org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java:403)
>         at 
> org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(TransactionResourceImpl.java:346)
>         at 
> org.apache.derby.impl.jdbc.EmbedConnection.handleException(EmbedConnection.java:2183)
>         at 
> org.apache.derby.impl.jdbc.ConnectionChild.handleException(ConnectionChild.java:81)
>         at 
> org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1325)
>         at 
> org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:625)
>         at <unknown class>.<unknown method>(Unknown Source)
>         at 
> org.apache.derbyTesting.functionTests.tests.multi.StressMultiTest$StressMultiRunnable.run(StressMultiTest.jav
> a:317)
>         at java.lang.Thread.run(Thread.java:803)
> Caused by: org.apache.derby.shared.common.sanity.AssertFailure: ASSERT FAILED 
> transaction table has null entry
>         at 
> org.apache.derby.shared.common.sanity.SanityManager.ASSERT(SanityManager.java:120)
>         at 
> org.apache.derby.impl.store.raw.xact.TransactionTable.getTransactionInfo(TransactionTable.java:968)
>         at 
> org.apache.derby.impl.store.raw.xact.XactFactory.getTransactionInfo(XactFactory.java:991)
>         at 
> org.apache.derby.impl.store.raw.RawStore.getTransactionInfo(RawStore.java:1153)
>         at 
> org.apache.derby.impl.store.access.RAMAccessManager.getTransactionInfo(RAMAccessManager.java:912)
>         at 
> org.apache.derby.impl.services.locks.Deadlock.buildException(Deadlock.java:266)
>         at 
> org.apache.derby.impl.services.locks.ConcurrentLockSet.lockObject(ConcurrentLockSet.java:613)
>         at 
> org.apache.derby.impl.services.locks.AbstractPool.lockObject(AbstractPool.java:117)
>         at 
> org.apache.derby.impl.store.raw.xact.RowLocking3.lockRecordForWrite(RowLocking3.java:248)
>         at 
> org.apache.derby.impl.store.access.heap.HeapController.lockRow(HeapController.java:504)
>         at 
> org.apache.derby.impl.store.access.heap.HeapController.lockRow(HeapController.java:638)
>         at 
> org.apache.derby.impl.store.access.btree.index.B2IRowLocking3.lockRowOnPage(B2IRowLocking3.java:335)
>         at 
> org.apache.derby.impl.store.access.btree.index.B2IRowLocking3._lockScanRow(B2IRowLocking3.java:628)
>         at 
> org.apache.derby.impl.store.access.btree.index.B2IRowLockingRR.lockScanRow(B2IRowLockingRR.java:112)
>         at 
> org.apache.derby.impl.store.access.btree.BTreeForwardScan.fetchRows(BTreeForwardScan.java:304)
>         at 
> org.apache.derby.impl.store.access.btree.BTreeScan.fetchNext(BTreeScan.java:1809)
>         at 
> org.apache.derby.impl.sql.execute.TableScanResultSet.getNextRowCore(TableScanResultSet.java:680)
>         at 
> org.apache.derby.impl.sql.execute.IndexRowToBaseRowResultSet.getNextRowCore(IndexRowToBaseRowResultSet.java:3
> 73)
>         at 
> org.apache.derby.impl.sql.execute.ProjectRestrictResultSet.getNextRowCore(ProjectRestrictResultSet.java:255)
>         at 
> org.apache.derby.impl.sql.execute.NormalizeResultSet.getNextRowCore(NormalizeResultSet.java:186)
>         at 
> org.apache.derby.impl.sql.execute.DMLWriteResultSet.getNextRowCore(DMLWriteResultSet.java:127)
>         at 
> org.apache.derby.impl.sql.execute.UpdateResultSet.collectAffectedRows(UpdateResultSet.java:424)
>         at 
> org.apache.derby.impl.sql.execute.UpdateResultSet.open(UpdateResultSet.java:246)
>         at 
> org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:384)
>         at 
> org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1235)
>         at 
> org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:625)
>         at 
> org.apache.derby.impl.jdbc.EmbedStatement.executeUpdate(EmbedStatement.java:175)
>         at 
> org.apache.derbyTesting.functionTests.tests.multi.StressMultiTest$StressMultiRunnable.update(StressMultiTest.
> java:471)
>         ... 2 more
> FAILURES!!!
> Tests run: 3, Failures: 0, Errors: 1 

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