Skip to content

Commit

Permalink
transaction must start and end within write lock. Since reverse order
Browse files Browse the repository at this point in the history
shows concurrent transactions inconsistent transient vs. peristent
structures.
  • Loading branch information
tamasblummer committed Jan 1, 2013
1 parent 7a72595 commit 96c6ffb
Showing 1 changed file with 43 additions and 17 deletions.
60 changes: 43 additions & 17 deletions src/main/java/com/bitsofproof/supernode/core/CachedBlockStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,12 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import com.bitsofproof.supernode.api.AddressConverter;
import com.bitsofproof.supernode.api.Difficulty;
Expand All @@ -58,9 +62,13 @@ public abstract class CachedBlockStore implements BlockStore
// not allowed to branch further back on trunk
private static final int FORCE_TRUNK = 100;
private static final long MIN_RELAY_TX_FEE = 10000;

@Autowired
private Chain chain;

@Autowired
PlatformTransactionManager transactionManager;

private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock ();

protected CachedHead currentHead = null;
Expand Down Expand Up @@ -522,27 +530,45 @@ private static class TransactionContext
TxOutCache resolvedInputs = new ImplementTxOutCache ();
}

@Transactional (propagation = Propagation.REQUIRED, rollbackFor = { Exception.class })
@Override
public void storeBlock (Blk b) throws ValidationException
public void storeBlock (final Blk b) throws ValidationException
{
try
{
// have to lock before transaction starts and unlock after finished.
// otherwise updates to transient vs. persistent structures are out of sync for a
// concurrent tx. This does not apply to methods using MANDATORY transaction annotation
// context since they must have been invoked within a transaction.
lock.writeLock ().lock ();

startBatch ();
lockedStoreBlock (b);
endBatch ();
}
catch ( ValidationException e )
{
cancelBatch ();
throw e;
}
catch ( Exception e )
{
cancelBatch ();
throw new ValidationException ("OTHER exception " + b.toWireDump (), e);
ValidationException e = new TransactionTemplate (transactionManager).execute (new TransactionCallback<ValidationException> ()
{
@Override
public ValidationException doInTransaction (TransactionStatus status)
{
try
{
startBatch ();
lockedStoreBlock (b);
endBatch ();
}
catch ( ValidationException e )
{
cancelBatch ();
return e;
}
catch ( Exception e )
{
cancelBatch ();
return new ValidationException ("OTHER exception " + b.toWireDump (), e);
}
return null;
}
});
if ( e != null )
{
throw e;
}
}
finally
{
Expand Down Expand Up @@ -1317,7 +1343,7 @@ public Blk getBlock (String hash)
return retrieveBlock (cached);
}

@Transactional (propagation = Propagation.REQUIRED, readOnly = true)
@Transactional (propagation = Propagation.MANDATORY, readOnly = true)
@Override
public void resolveTransactionInputs (Tx t, TxOutCache resolvedInputs) throws ValidationException
{
Expand All @@ -1333,7 +1359,7 @@ public void resolveTransactionInputs (Tx t, TxOutCache resolvedInputs) throws Va
}
}

@Transactional (propagation = Propagation.REQUIRED, readOnly = true)
@Transactional (propagation = Propagation.MANDATORY, readOnly = true)
@Override
public boolean validateTransaction (Tx t, TxOutCache resolvedInputs) throws ValidationException
{
Expand Down

0 comments on commit 96c6ffb

Please sign in to comment.