On 08/06/12 19:55, Simon Helsen wrote:
hi again,
k, so, it is tricky to distill a test case out of our framework because
this one is based on multiple threads, but I am debugging it myself
instead.
So, I put the breakpoint in DatasetControlMRSW.policyError where the cme
is thrown. When I do that and rerun the test suite, I get into a scenario
where 4 threads hang on the breakpoint. 3 of these are 'read' threads and
1 is a 'write' thread. Now, the writeCounter says it has 4 (and the
readCounter is 0), which is why the cme is thrown. So, the question is why
the writeCounter says 4.
In order to find that out, I set a different breakpoint at startUpdate in
DatasetControlMRSW. I notice that it came from a query, i.e. a READ
transaction. The violating code is this:
@Override
protected void _begin(ReadWrite readWrite)
{
synchronized(lock)
{
if ( ! haveUsedInTransaction )
getBaseDatasetGraph().sync() ;
haveUsedInTransaction = true ;
DatasetGraphTxn dsgTxn = sConn.begin(readWrite) ;
txn.set(dsgTxn) ;
inTransaction.set(true) ;
}
}
The bit
if ( ! haveUsedInTransaction )
getBaseDatasetGraph().sync() ;
is the problem. It calls prefixes.sync() which calls nodeTupleTable.sync()
which calls startWrite() ;
any ideas how to fix this?
Simon
sync's are writes.
It's making sure that any non-transactional changes are put to disk
before the whole thing swicths into transactional mode. Not a usage to
be encouraged but the code needs to be safe.
It's hard to tell without how the DatasetGraphTransaction's get made but
try changing
synchronized(lock)
to
synchronized(sConn)
(the test suite passes - not surprising as it is a more conservative
choice than the built code.)
It's late here - but that might be the cause. Otherwise, how are the
dataset being made? There seem to be several about - that should be OK,
as should multiple threads per DatasetGraphTransaction (transactions are
per thread). Which style are you using?
Andy