LATEST VERSION: 9.6.0 - RELEASE NOTES
Pivotal GemFire® v9.6

Design Considerations

Designs that incorporate more complex features introduce further considerations. This section discusses how transactions interact with other GemFire features.

Colocate Partitioned Regions

For performance, transactions that operate on more than one partitioned region require that those partitioned regions colocate their entries. Colocate Data from Different Partitioned Regions describes how to colocate entries.

Region Operations Return References

For performance, server-invoked region operations return references to region entries. Any assignment to that reference changes the entry within the region. This subverts the system’s ability to maintain consistency and the callback chain for handlers such as cache writers and cache loaders.

Changing an entry using a reference from within a transaction executing on a server has the same consistency issues, but is even worse, as the change will not be seen as part of the transactional state.

There are two ways to work with a reference: make a copy, or configure the system to return copies instead of references. There is a performance penalty to having the system return copies. Both ways are detailed in Safe Entry Modification.

First Operation with Mixed Region Types

When more than one region participates in a transaction, and there is at least one partitioned and at least one replicated region, the code must do its first operation on the partitioned region to avoid a TransactionDataNotColocatedException. Write the transaction to do its first operation on a partitioned region, even if the operation will be spurious.

Allowing Transactions to Work on Persistent Regions

GemFire’s implementation of atomic transactions prohibits regions with persistence from participating in transactions. The invocation of a persistent region operation within a transaction throws an UnsupportedOperationException with an associated message of

Operations on persist-backup regions are not allowed because this thread
has an active transaction

An application that wishes to allow operations on a persistent region during a transaction can set this system property:

-Dgemfire.ALLOW_PERSISTENT_TRANSACTIONS=true

Setting this system property eliminates the exception. It does not change the fact that atomicity is not enforced for disk writes that occur with the commit of a transaction. A server crash during the commit may succeed in some, but not all of the disk writes.

Mixing Transactions with Queries and Indexes

Queries and query results reflect region state, and not any state or changes that occur within a transaction. Likewise, the contents and updates to an index do not intersect with any changes made within a transaction. Therefore, do not mix transactions with queries or indexed regions.

Mixing Transactions with Eviction

LRU eviction and transactions work well together. Any eviction operation on a region entry that is operated on from within a transaction is deferred until the transaction is committed. Further, because any entry touched by the transaction has had its LRU clock reset, eviction is not likely to choose those entries as victims immediately after the commit.

Mixing Transactions with Expiration

A transaction disables expiration on any region entries affected by the transaction.

Changing the Handling of Dirty Reads

An application requiring a strict, but slower isolation model, such that dirty reads of transitional states are not allowed, should set a property and encapsulate read operations within the transaction. Configure this strict isolation model with the property:

-Dgemfire.detectReadConflicts=true

This property causes read operations to succeed only when they read a consistent pre- or post-transactional state. If not consistent, GemFire throws a CommitConflictException.