org.multiverse.stms
Class AbstractTransaction<C extends AbstractTransactionConfiguration,S extends AbstractTransactionSnapshot>

java.lang.Object
  extended by org.multiverse.stms.AbstractTransaction<C,S>
All Implemented Interfaces:
Transaction, MultiverseConstants

public abstract class AbstractTransaction<C extends AbstractTransactionConfiguration,S extends AbstractTransactionSnapshot>
extends java.lang.Object
implements Transaction, MultiverseConstants

An abstract Transaction implementation that contains most of the plumbing logic. Extend this and prevent duplicate logic.

The do-methods can be overridden.

AbstractTransaction requires the clock.time to be at least 1. It used the version field to encode the transaction state. See the version field for more information.

Author:
Peter Veentjer.

Field Summary
static int ABORTED
           
static int ACTIVE
           
static int COMMITTED
           
protected  C config
           
static int NEW
           
static int PREPARED
           
protected  int statusInt
           
protected  long timeoutNs
           
protected  long version
           
 
Fields inherited from interface org.multiverse.MultiverseConstants
___BUGSHAKER_ENABLED, ___TRACING_ENABLED
 
Constructor Summary
AbstractTransaction(C config)
           
 
Method Summary
 void abort()
          Aborts this Transaction.
 void commit()
          Commits this Transaction.
protected  void doAbortActive()
          Method is designed to be overridden to add custom behavior on the abort of the transaction.
protected  void doAbortPrepared()
           
protected  void doPrepare()
           
protected  boolean doRegisterRetryLatch(Latch latch, long wakeupVersion)
          Register retry.
protected  void doReset()
           
protected  void doStart()
          Method is designed to be overridden to add custom behavior on the init of the transaction.
 void endOr()
           
 void endOrAndStartElse()
           
 int getAttempt()
          Gets the current attempt (so the number of tries this transaction already had).
 TransactionConfiguration getConfiguration()
          Gets the TransactionConfiguration that is used by this Transaction.
 long getReadVersion()
          Returns the clock version of the stm when this Transaction started.
 long getRemainingTimeoutNs()
          Gets the remaining timeout in nanoseconds.
protected  S getSnapshot()
           
 TransactionStatus getStatus()
          Returns the status of this Transaction.
 Stm getStm()
          Returns the Stm that started this Transaction.
 TransactionFactory getTransactionFactory()
          Returns the TransactionFactory that started this Transaction.
protected  void makeChangesPermanent()
           
 void prepare()
          Prepares this transaction to be committed.
 void registerLifecycleListener(TransactionLifecycleListener listener)
          Registers a TransactionLifecycleListener on this Transaction.
 void registerRetryLatch(Latch latch)
          Registers the retry Latch on this Transaction.
 void reset()
          Resets this Transaction so it can be reused.
 void setAttempt(int attempt)
          Sets the current attempt.
 void setRemainingTimeoutNs(long newTimeoutNs)
          Sets the remaining timeout in nanoseconds.
 void start()
          Starts the Transaction.
 void startOr()
           
protected  void storeSnapshot(S snapshot)
           
protected  S takeSnapshot()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

config

protected final C extends AbstractTransactionConfiguration config

version

protected long version

NEW

public static final int NEW
See Also:
Constant Field Values

ACTIVE

public static final int ACTIVE
See Also:
Constant Field Values

PREPARED

public static final int PREPARED
See Also:
Constant Field Values

COMMITTED

public static final int COMMITTED
See Also:
Constant Field Values

ABORTED

public static final int ABORTED
See Also:
Constant Field Values

statusInt

protected int statusInt

timeoutNs

protected long timeoutNs
Constructor Detail

AbstractTransaction

public AbstractTransaction(C config)
Method Detail

getAttempt

public final int getAttempt()
Description copied from interface: Transaction
Gets the current attempt (so the number of tries this transaction already had). Value will always be equal or larger than 0.

Specified by:
getAttempt in interface Transaction
Returns:
the current attempt.

setAttempt

public final void setAttempt(int attempt)
Description copied from interface: Transaction
Sets the current attempt.

This normally isn't called from the user code, it is the task of the stm internals and the transaction management to use the attempt.

Specified by:
setAttempt in interface Transaction
Parameters:
attempt - the current attempt

getRemainingTimeoutNs

public final long getRemainingTimeoutNs()
Description copied from interface: Transaction
Gets the remaining timeout in nanoseconds. Long.MAX_VALUE indicates that no timeout should be used.

Specified by:
getRemainingTimeoutNs in interface Transaction
Returns:
the remaining timeout.

setRemainingTimeoutNs

public final void setRemainingTimeoutNs(long newTimeoutNs)
Description copied from interface: Transaction
Sets the remaining timeout in nanoseconds. Long.MAX_VALUE indicates that no timeout should be used.

This normally isn't called from the user code, it is task of the stm internals and the transaction management to use the timeout.

Specified by:
setRemainingTimeoutNs in interface Transaction
Parameters:
newTimeoutNs - the timeout.

getReadVersion

public final long getReadVersion()
Description copied from interface: Transaction
Returns the clock version of the stm when this Transaction started. This version is needed to provide a transaction level read consistent view (so a transaction will always see a stable view of the objects at some point in time).

The value is unspecified once the Transaction is aborted or committed.

Method depends on long as time, and is going to be removed or replaced in the future.

Specified by:
getReadVersion in interface Transaction
Returns:
the version of the stm when this Transaction started.

getStatus

public final TransactionStatus getStatus()
Description copied from interface: Transaction
Returns the status of this Transaction.

Specified by:
getStatus in interface Transaction
Returns:
the status of this Transaction.

getConfiguration

public final TransactionConfiguration getConfiguration()
Description copied from interface: Transaction
Gets the TransactionConfiguration that is used by this Transaction.

Specified by:
getConfiguration in interface Transaction
Returns:
the used TransactionConfiguration.

getStm

public final Stm getStm()
Description copied from interface: Transaction
Returns the Stm that started this Transaction.

Specified by:
getStm in interface Transaction
Returns:
the Stm that started this Transaction.

getTransactionFactory

public final TransactionFactory getTransactionFactory()
Description copied from interface: Transaction
Returns the TransactionFactory that started this Transaction.

Specified by:
getTransactionFactory in interface Transaction
Returns:
the TransactionFactory that started this Transaction.

doStart

protected void doStart()
Method is designed to be overridden to add custom behavior on the init of the transaction.


doReset

protected void doReset()

start

public void start()
Description copied from interface: Transaction
Starts the Transaction. Transaction normally started as New.

If a clock based stm is used (like the AlphaStm), when the transaction is New, the readversion is not set. When it is started, it is set. Based on this readversion the transaction is able to construct a read consistent view. But the sooner the read version is set, the higher the chance that a transaction runs out of history to read from.

Specified by:
start in interface Transaction

registerLifecycleListener

public final void registerLifecycleListener(TransactionLifecycleListener listener)
Description copied from interface: Transaction
Registers a TransactionLifecycleListener on this Transaction. It can be used to receive a callback from the transaction if the TransactionStatus of that transaction. Without this functionality it would not be possible to execute compensating or deferred action once a transaction aborts or commits.

If the execution of one of the listeners fails, the others won't be executed. If one of the listeners fails before the commit/abort, the transaction is aborted (no matter what).

The listeners are executed in the order they are registered.

If the same listener is added multiple times, it will be notified multiple times.

The listener will be executed on the thread that starts the commit/abort.

If the listener is added after the Transaction is prepared, the preCommit event will not be called on the listener.

If the listener accesses the stm after the transaction has been committed or aborted, it could see changes made after that transaction. So all assumptions about state are possibly wrong so one needs to take care of re-validating state if needed.

A good use case of this feature is starting up threads. If you need to start threads, you don't want to start them immediately because eventually the transaction could be aborted.

The registration is 'transactional', so when the transaction is restarted, the listeners need to be registered again. In most cases this is the behavior wanted because listeners are added inside the atomic 'block' and this block is re-executed when a failure occurs.

Specified by:
registerLifecycleListener in interface Transaction
Parameters:
listener - the TransactionLifecycleListener to registerLifecycleListener

prepare

public final void prepare()
Description copied from interface: Transaction
Prepares this transaction to be committed. It can lock resources to make sure that no conflicting changes are made after the transaction has been prepared. If the transaction already is prepared, the call is ignored. If the prepare fails, the transaction automatically is aborted.

It is very important that the transaction eventually commits or aborts, if it doesn't no other transaction reading/writing the committed resources, can't commit.

Specified by:
prepare in interface Transaction

doPrepare

protected void doPrepare()

reset

public final void reset()
Description copied from interface: Transaction
Resets this Transaction so it can be reused. After the reset is executed the Transaction is back to the TransactionStatus.New state.

It doesn't matter what the transaction state of the transaction is. This is the preferred way to reuse a transaction (e.g. when a ControlFlowError or when an old transaction on the ThreadLocalTransaction is found that can be reused.

If the Transaction is prepared or committed, it will be aborted before it is reset. If there are TransactionLifecycleListeners that cause problems while executing the pre/post abort notification, the transaction will be aborted and the exception will be propagated.

Specified by:
reset in interface Transaction

abort

public final void abort()
Description copied from interface: Transaction
Aborts this Transaction. This means that the changes made in this transaction are not committed. It depends on the implementation if this operation is simple (ditching objects for example), or if changes need to be rolled back. If an exception is thrown while executing the abort, the transaction is still aborted. And example of such a situation is a pre-abort task that fails. So the transaction always is aborted (unless it is committed).

If the Transaction already is aborted, the call is ignored.

Specified by:
abort in interface Transaction

doAbortPrepared

protected void doAbortPrepared()

doAbortActive

protected void doAbortActive()
Method is designed to be overridden to add custom behavior on the abort of the transaction.


commit

public final void commit()
Description copied from interface: Transaction
Commits this Transaction. If the Transaction is:
  1. new: is is started and following the same flow as an active transaction. This is done so that the lifecyclelisteners work.
  2. active: it is prepared for commit and then committed
  3. prepared: it is committed (so changes persisted)
  4. aborted: a DeadTransactionException is thrown
  5. committed: a DeadTransactionException is thrown
So it is safe to call while active or prepared.

Transaction will be aborted if the commit does not succeed.

Commit will not throw any validation exceptions after the transaction is prepared.

Specified by:
commit in interface Transaction

makeChangesPermanent

protected void makeChangesPermanent()

registerRetryLatch

public final void registerRetryLatch(Latch latch)
Description copied from interface: Transaction
Registers the retry Latch on this Transaction. This functionality is required for the retry mechanism (so blocking!) and is something different than 'just' restarting. The Latch contains all the 'waiting' logic, so you can do timed and non interruptible timeouts on that structure. A latch can be compared to a Future because it also pops closed once some event occurs (an interesting write in the case of a Latch).

Specified by:
registerRetryLatch in interface Transaction
Parameters:
latch - the Latch to register.

doRegisterRetryLatch

protected boolean doRegisterRetryLatch(Latch latch,
                                       long wakeupVersion)
Register retry. Default implementation returns 0, indicating that a retry is not possible.

This method is designed to be overridden.

Parameters:
latch - the latch to registerLifecycleListener. Value will never be null.
wakeupVersion - the minimal version of the transactional object to wakeup for.
Returns:
true if there were tracked reads (so the latch was opened or registered at at least 1 transactional object)

startOr

public final void startOr()

endOr

public final void endOr()

endOrAndStartElse

public final void endOrAndStartElse()

takeSnapshot

protected S takeSnapshot()

getSnapshot

protected S getSnapshot()

storeSnapshot

protected void storeSnapshot(S snapshot)


Copyright © 2008-2010 Multiverse. All Rights Reserved.