public interface CacheTransactionManager
The CacheTransactionManager interface allows applications to manage transactions on a per
Cache
basis.
The life cycle of a GemFire transaction starts with a begin operation. The life cycle ends with
either a commit or rollback operation. Between the begin and the commit/rollback are typically
Region
operations. In general, those that either create, destroy, invalidate or update
Region.Entry
are considered transactional, that is they modify transactional state.
A GemFire transaction may involve operations on multiple regions, each of which may have different attributes.
While a GemFire transaction and its operations are invoked in the local VM, the resulting transaction state is distributed to other VM's at commit time as per the attributes of each participant Region.
A transaction can have no more than one thread associated with it and conversely a thread can only operate on one transaction at any given time. Child threads will not inherit the existing transaction.
Each of the following methods operate on the current thread. All methods throw
CacheClosedException
if the Cache is closed.
GemFire Transactions currently only support Read Committed isolation. In addition, they are optimistic transactions in that write locking and conflict checks are performed as part of the commit operation.
For guaranteed Read Committed isolation, avoid making "in place" changes, because such changes will be "seen" by other transactions and break the Read Committed isolation guarantee. e.g.
CacheTransactionManager txMgr = cache.getCacheTransactionManager(); txMgr.begin(); StringBuilder s = (StringBuilder) r.get("stringBuf"); s.append("Changes seen before commit. NOT Read Committed!"); r.put("stringBuf", s); txMgr.commit();
To aid in creating copies, the "copy on read" Cache
attribute and the
CopyHelper.copy(T)
method are provided. The following is a Read Committed
safe example using the CopyHelper.copy
method.
CacheTransactionManager txMgr = cache.getCacheTransactionManager(); txMgr.begin(); Object o = r.get("stringBuf"); StringBuilder s = (StringBuilder) CopyHelper.copy(o); s.append("Changes unseen before commit. Read Committed."); r.put("stringBuf", s); txMgr.commit();
Its important to note that creating copies can negatively impact both performance and memory consumption.
Partitioned Regions, Distributed No Ack and Distributed Ack Regions are supported (see
AttributesFactory
for Scope). For both scopes, a consistent configuration (per VM) is
enforced.
Global Regions, client Regions (see org.apache.geode.cache.client package) and persistent Regions
(see DiskWriteAttributes
) do not support transactions.
When PartitionedRegions are involved in a transaction, all data in the transaction must be colocated together on one data node. See the GemFire Developer Guide for details on using transactions with Partitioned Regions.
Cache
Modifier and Type | Method and Description |
---|---|
void |
addListener(TransactionListener aListener)
Adds a transaction listener to the end of the list of transaction listeners on this cache.
|
void |
begin()
Creates a new transaction and associates it with the current thread.
|
void |
commit()
Commit the transaction associated with the current thread.
|
boolean |
exists()
Reports the existence of a Transaction for this thread
|
boolean |
exists(TransactionId transactionId)
Reports the existence of a transaction for the given transactionId.
|
TransactionListener |
getListener()
Deprecated.
as of GemFire 5.0, use
getListeners() instead |
TransactionListener[] |
getListeners()
Returns an array of all the transaction listeners on this cache.
|
TransactionId |
getTransactionId()
Returns the transaction identifier for the current thread
|
TransactionWriter |
getWriter()
Returns the current
TransactionWriter |
void |
initListeners(TransactionListener[] newListeners)
Removes all transaction listeners, calling
CacheCallback.close() on each of them, and
then adds each listener in the specified array. |
boolean |
isDistributed()
Returns the execution mode of transactions
|
boolean |
isSuspended(TransactionId transactionId)
This method can be used to determine if a transaction with the given transaction identifier is
currently suspended locally.
|
void |
removeListener(TransactionListener aListener)
Removes a transaction listener from the list of transaction listeners on this cache.
|
void |
resume(TransactionId transactionId)
On the current thread, resumes a transaction that was previously suspended using
suspend() |
void |
rollback()
Roll back the transaction associated with the current thread.
|
void |
setDistributed(boolean distributed)
Sets whether transactions should be executed in distributed or non-distributed mode.
|
TransactionListener |
setListener(TransactionListener newListener)
Deprecated.
as of GemFire 5.0, use
addListener(org.apache.geode.cache.TransactionListener) or initListeners(org.apache.geode.cache.TransactionListener[]) instead. |
void |
setWriter(TransactionWriter writer)
Set the TransactionWriter for the cache
|
TransactionId |
suspend()
Suspends the transaction on the current thread.
|
boolean |
tryResume(TransactionId transactionId)
On the current thread, resumes a transaction that was previously suspended using
suspend() . |
boolean |
tryResume(TransactionId transactionId,
long time,
TimeUnit unit)
On the current thread, resumes a transaction that was previously suspended using
suspend() , or waits for the specified timeout interval if the transaction has not been
suspended. |
void begin()
IllegalStateException
- if the thread is already associated with a transactionvoid commit() throws CommitConflictException
CommitConflictException
.
If the commit operation succeeds, it returns after the transaction state has been merged with
committed state. When this method completes, the thread is no longer associated with a
transaction.IllegalStateException
- if the thread is not associated with a transactionCommitConflictException
- if the commit operation fails due to a write conflict.TransactionDataNodeHasDepartedException
- if the node hosting the transaction data has
departed. This is only relevant for transaction that involve PartitionedRegions.TransactionDataNotColocatedException
- if at commit time, the data involved in the
transaction has moved away from the transaction hosting node. This can only happen if
rebalancing/recovery happens during a transaction that involves a PartitionedRegion.TransactionInDoubtException
- when GemFire cannot tell which nodes have applied the
transaction and which have not. This only occurs if nodes fail mid-commit, and only
then in very rare circumstances.void rollback()
IllegalStateException
- if the thread is not associated with a transactionTransactionId suspend()
resume(TransactionId)
void resume(TransactionId transactionId)
suspend()
transactionId
- the transaction to resumeIllegalStateException
- if the thread is associated with a transaction or if
isSuspended(TransactionId)
would return false for the given transactionIdtryResume(TransactionId)
boolean isSuspended(TransactionId transactionId)
transactionId
- a transaction identifierexists(TransactionId)
boolean tryResume(TransactionId transactionId)
suspend()
.
This method is equivalent to
if (isSuspended(txId)) { resume(txId); }except that this action is performed atomically
transactionId
- the transaction to resumeboolean tryResume(TransactionId transactionId, long time, TimeUnit unit)
suspend()
, or waits for the specified timeout interval if the transaction has not been
suspended. This method will return if:
exists(TransactionId)
returns false.transactionId
- the transaction to resumetime
- the maximum time to waitunit
- the time unit of the time
argumenttryResume(TransactionId)
boolean exists(TransactionId transactionId)
transactionId
- the given transaction identifierisSuspended(TransactionId)
boolean exists()
TransactionId getTransactionId()
@Deprecated TransactionListener getListener()
getListeners()
insteadIllegalStateException
- if more than one listener exists on this cacheTransactionListener[] getListeners()
TransactionListener
s; an empty array if no listeners@Deprecated TransactionListener setListener(TransactionListener newListener)
addListener(org.apache.geode.cache.TransactionListener)
or initListeners(org.apache.geode.cache.TransactionListener[])
instead.newListener
- the TransactionListener to register with the Cache. Use a null
to deregister the current listener without registering a new one.IllegalStateException
- if more than one listener exists on this cachevoid addListener(TransactionListener aListener)
aListener
- the user defined transaction listener to add to the cache.IllegalArgumentException
- if aListener
is nullvoid removeListener(TransactionListener aListener)
CacheCallback.close()
will be called on it; otherwise does nothing.aListener
- the transaction listener to remove from the cache.IllegalArgumentException
- if aListener
is nullvoid initListeners(TransactionListener[] newListeners)
CacheCallback.close()
on each of them, and
then adds each listener in the specified array.newListeners
- a possibly null or empty array of listeners to add to this cache.IllegalArgumentException
- if the newListeners
array has a null elementvoid setWriter(TransactionWriter writer)
writer
- the TransactionWriter for the cacheTransactionWriter
TransactionWriter getWriter()
TransactionWriter
TransactionWriter
setWriter(TransactionWriter)
void setDistributed(boolean distributed)
distributed
- whether transactions should be executed in distributed or non-distributed
modeIllegalStateException
- if a transaction is already in progress and this method sets the
distributed mode to a different value.boolean isDistributed()