Comparing Transactional and Non-Transactional Operations
Between the begin operation and the commit or rollback operation are a series of ordinary Geode operations. When they are launched from within a transaction, the Geode operations can be classified into two types:
- Transactional operations affect the transactional view
- Non-transactional operations do not affect the transactional view
An operation that acts directly on the cache does not usually act on the transactional view.
Transactional Operations
The CacheTransactionManager
methods are the only ones used specifically for cache operations. Otherwise, you use the same methods as usual. Most methods that run within a transaction affect the transactional view, and they do not change the cache until the transaction commits. Methods that behave this way are considered transactional operations. Transactional operations are classified in two ways: whether they modify the transactional view or the cache itself, and whether they create write conflicts with other transactions.
In general, methods that create, destroy, invalidate, update, or read region entries are transactional operations.
Transactional operations that can cause write conflicts are those that modify an entry, such as put, a load done to satisfy a get operation, create, delete, local delete, invalidate and local invalidate.
Transactional read operations do not cause conflicts directly, but they can modify the transactional view. Read operations look for the entry in the transaction view first and then, if necessary, go to the cache. If the entry is returned by a cache read, it is stored as part of the transactional view. At commit time, the transaction uses the initial snapshot of the entry in the view to discover write conflicts.
Non-Transactional Operations
A few methods, when invoked within a transaction, have no effect on the transactional view, but they have an immediate effect on the cache. They are considered non-transactional operations. Often, non-transactional operations are administrative, such as Region.destroy
and Region.invalidate
. These operations are not supported within a transaction. If you call them, the system throws an exception of type UnsupportedOperationInTransactionException
.
Entry Operations
Note: Transactional entry operations can be rolled back.
Operations | Methods | Transactional | Write Conflict |
---|---|---|---|
create | Region.create, put, putAll, Map.put, putAll |
yes | yes |
modify | Region.put, putAll, Map.put, putAll, Region.Entry.setValue, Map.Entry.setValue |
yes | yes |
load | Region.get, Map.get |
yes | yes |
creation or update using netSearch |
Region.get, Map.get |
yes | no |
destroy: local and distributed | Region.localDestroy, destroy, remove, Map.remove |
yes | yes |
invalidate: local and distributed | Region.localInvalidate, invalidate |
yes | yes |
set user attribute | Region.Entry.setUserAttribute |
yes | yes |
read of a single entry | Region.get, getEntry, containsKey, containsValue, containsValueForKey |
yes | no |
read of a collection of entries | Region.keySet, entrySet, values |
Becomes transactional when you access the keys or values within the collection. | no |
Some transactional write operations also do a read before they write, and these can complete a transactional read even when the write fails. The following table of entry operations notes the conditions under which this can happen.
Note: These operations can add a snapshot of an entry to the transaction’s view even when the write operation does not succeed.
Operations | Methods | Reads Without Writing |
---|---|---|
create | Region.create |
when it throws an EntryExistsException |
destroy: local and distributed | Region.localDestroy, destroy |
when it throws an EntryNotFoundException |
invalidate: local and distributed | Region.localInvalidate, invalidate |
when it throws an EntryNotFoundException or the entry is already invalid |
Region Operations
When you create a region in a transaction, any data from the getInitialImage operation goes directly into the cache, rather than waiting for the transaction to commit.
Operations | Methods | Affected | Write Conflict |
---|---|---|---|
destroy: local and distributed | Region.localDestroyRegion, destroyRegion |
cache | yes |
invalidate: local and distributed | Region.localInvalidateRegion, invalidateRegion |
cache | yes |
clear: local and distributed | Region.localClear, clear, Map.clear |
cache and transaction | no |
close | Region.close |
cache | yes |
mutate attribute | Region.getAttributesMutator methods |
cache | no |
set user attribute | Region.setUserAttribute |
cache | no |
Cache Operations
When you create a region in a transaction, any data from the getInitialImage operation goes directly into the cache, rather than waiting for the transaction to commit.
Operations | Methods | Affected State | Write Conflict |
---|---|---|---|
create | createRegionFactory().create() |
committed | no |
close | close |
committed | yes |
No-Ops
Any operation that has no effect in a non-transactional context remains a no-op in a transactional context. For example, if you do two localInvalidate
operations in a row on the same region, the second localInvalidate
is a no-op. No-op operations do not:
- Cause a listener invocation
- Cause a distribution message to be sent to other members
- Cause a change to an entry
- Cause any conflict
A no-op can do a transactional read.