public interface Txn
Stm
. The transaction make sure that changes on TxnObject
instances are:
IsolationLevel
or LockMode
used how strict the isolation is.A Txn is not thread-safe (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 the TxnThreadLocal
or other
thread specific state like the stackframe of a method (this is an issue when instrumentation is used since the stackframe
is likely to be enhanced to include the Txn as a local variable.
It is possible to listen to a Txn when it aborts/prepares/commits/starts. There are 2 different flavors of listeners:
register(org.multiverse.api.lifecycle.TxnListener)
method. If the transactions aborts/commits
these listeners are removed. So if the transaction is retried, the listeners need to be registered (this is easy since
the logic inside the transactional closure that did the register, is executed again.
TxnFactoryBuilder.addPermanentListener(org.multiverse.api.lifecycle.TxnListener)
or it can be done on the Stm level. Permanent listeners are suited for products that want to integrate with Multiverse and always
execute some logic at important transaction events. Registration of permanent can also be done on the Stm
level. See
the implementations for more details. Permanent listeners are always executed after the normal listeners.
Txn instances should not be stored since they are likely to be pooled by the STM. So it could be that the same transaction instance is re-used to execute a completely unrelated piece of logic, and it can also be that different instances are used to execute the same logic.
Modifier and Type | Method and Description |
---|---|
void |
abort()
Aborts this Txn.
|
void |
commit()
Commits this Txn.
|
int |
getAttempt()
Gets the current attempt (so the number of tries this transaction already had).
|
TxnConfig |
getConfig()
Returns the TxnConfig used by this Txn.
|
long |
getRemainingTimeoutNs()
Gets the remaining timeout in nanoseconds.
|
TxnStatus |
getStatus()
Returns the status of this Txn.
|
boolean |
isAbortOnly()
Checks if this Txn is abort only (so will always fail when committing or preparing).
|
void |
prepare()
Prepares this transaction to be committed.
|
void |
register(TxnListener listener)
Registers a TxnListener.
|
void |
retry()
Retries the transaction.
|
void |
setAbortOnly()
Signals that the only possible outcome of the Txn is one that aborts.
|
TxnConfig getConfig()
Because the Txn can be reused, the TxnConfig used by this Txn doesn't need to be constant.
TxnStatus getStatus()
int getAttempt()
TxnConfig.getMaxRetries()
long getRemainingTimeoutNs()
The remaining timeout only is decreased if a transaction blocks on a retry or when doing a backoff.
void commit()
Txn will always be aborted if the commit does not succeed.
Commit will not throw a ReadWriteConflict
after the transaction is prepared.
So if prepared successfully, a commit will always succeed.
If there are TxnListeners (either normal ones or permanent ones) and they thrown a RuntimeException
or Error
, this will be re-thrown. If a listener fails after the prepare/commit the transaction still is
committed.
ReadWriteConflict
- if the commit failed. Check the class hierarchy of the ReadWriteConflict for more information.IllegalTxnStateException
- if the Txn is not in the correct
state for this operation.void prepare()
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.
ReadWriteConflict
- if the transaction can't be prepared.DeadTxnException
- if the transaction already is committed or aborted.void abort()
If the Txn already is aborted, the call is ignored.
IllegalTxnStateException
- if the Txn is not in the correct state for this operation.void retry()
RetryError
is thrown which is caught by the TxnExecutor
.TxnExecutionException
- if the transaction is not in a legal state for
this operation.ControlFlowError
void setAbortOnly()
AbortOnlyException
is thrown.
This method is not threadsafe, so can only be called by the thread that used the transaction.
IllegalTxnStateException
- if the transaction is not active.ControlFlowError
boolean isAbortOnly()
This method is not threadsafe, so can only be called by the thread that used the transaction.
DeadTxnException
- if the transaction is committed/aborted.void register(TxnListener listener)
TxnFactoryBuilder.addPermanentListener(org.multiverse.api.lifecycle.TxnListener)
.
If a TxnListener is added more than once, it is executed more than once. No checks are made. The permanent listeners are executed in the order they are added.
If a TxnListener throws an Error/RuntimeException and the transaction still is alive, it is aborted. For compensating and deferred actions this is not an issue, but for the PrePrepare state or the state it could since the transaction is aborted.
listener
- the listener to add.NullPointerException
- if listener is null. If the transaction is still alive, it is aborted.IllegalTxnStateException
- if the transaction is not in the correct
state (e.g. aborted or committed).ControlFlowError
Copyright © 2020. All rights reserved.