org.multiverse.api
Interface Transaction

All Known Implementing Classes:
AbstractTransaction

public interface Transaction

All changes on transaction objects must be done through a Transaction. The transaction make sure that changes on java objects are:

Thread-safety
A Transaction is not thread-safe to use (just like a Hibernate Session is not thread-safe to use). It can be handed over from thread to thread, but one needs to be really careful with threadlocals. Although the Stm/Transaction implementation don't care about threadlocals, the stuff in front (templates, instrumented code etc) could depend on threadlocals.

Listen to lifecycles
It is possible to listen to a Transaction when it aborts, or commits. This can be done with the registerLifecycleListener(TransactionLifecycleListener).

When the Transaction is reset, the lifecycle tasks are dropped. So the lifecycle task need to be registered again.

Blocking
It is possible to let a transaction block until some state changes has happened; comparable with the waitset/Condition functionality already provided. For more information see the registerRetryLatch(Latch).

Because a custom Latch implementation can be provided, you have a lot of control on the blocking behavior. But atm it is not possible to get fairness on when the Latch is opened. Policies to customize starvation, lifelocking, deadlocking will be added in the future.

Author:
Peter Veentjer.

Method Summary
 void abort()
          Aborts this Transaction.
 void commit()
          Commits this Transaction.
 int getAttempt()
           
 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()
           
 TransactionStatus getStatus()
          Returns the status of this Transaction.
 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 restart()
          Restarts this Transaction.
 void setAttempt(int attempt)
           
 void setRemainingTimeoutNs(long timeoutNs)
           
 

Method Detail

getConfiguration

TransactionConfiguration getConfiguration()
Gets the TransactionConfiguration that is used by this Transaction.

Returns:
the used TransactionConfiguration.

getReadVersion

long getReadVersion()
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.

Returns:
the version of the stm when this Transaction started.

getStatus

TransactionStatus getStatus()
Returns the status of this Transaction.

Returns:
the status of this Transaction.

commit

void commit()
Commits this Transaction. If the Transaction is:
  1. active: it is prepared for commit and then committed
  2. prepared: it is committed (so changes persisted)
  3. aborted: a DeadTransactionException is thrown
  4. 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.

Throws:
WriteConflict - if the commit failed. Check the class hierarchy of the WriteConflict for more information.
DeadTransactionException - if this transaction already is aborted.

prepare

void prepare()
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.

Throws:
WriteConflict - if the transaction can't be prepared.
DeadTransactionException - if the transaction already is committed or aborted.

abort

void abort()
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.

Throws:
DeadTransactionException - if this transaction already is committed

restart

void restart()
Restarts this Transaction. It doesn't matter what the transaction state of the transaction is. This is the preferred way to restart a transaction once a recoverable exception or retry occurred.

If the Transaction is prepared or committed, it will be aborted before it is restarted. 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.


registerRetryLatch

void registerRetryLatch(Latch latch)
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).

Parameters:
latch - the Latch to register.
Throws:
NullPointerException - if latch is null.
NoRetryPossibleException - if the retry can't make progress, e.g. because the transaction has not loaded any object.
DeadTransactionException - if this transaction already is committed or aborted.
UnsupportedOperationException - if the Transaction doesn't support this operation (for example because it doesn't do readtracking).

registerLifecycleListener

void registerLifecycleListener(TransactionLifecycleListener listener)
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.

Parameters:
listener - the TransactionLifecycleListener to registerLifecycleListener
Throws:
NullPointerException - if listener is null.
DeadTransactionException - if transaction already is aborted or committed.

getRemainingTimeoutNs

long getRemainingTimeoutNs()

setRemainingTimeoutNs

void setRemainingTimeoutNs(long timeoutNs)

getAttempt

int getAttempt()

setAttempt

void setAttempt(int attempt)


Copyright © 2008-2010 Multiverse. All Rights Reserved.