Supported Transaction Isolation Levels
GemFire XD supports several transaction isolation levels. It does not support the SERIALIZABLE isolation level, nested transactions, or savepoints.
- NONE. By default, connections in GemFire XD do not engage in transactions, unlike in other databases (see Data Consistency Concepts. This corresponds to the JDBC TRANSACTION_NONE isolation level (or IsolationLevel.Chaos in ADO.NET), or the "SET ISOLATION RESET" SQL command). However, this default behavior does not mean that there is no isolation and that connections have access to uncommitted state from other in-process transactions. The default consistency model without transactions is described in Understanding the Data Consistency Model.
- READ_UNCOMMITTED. GemFire XD internally upgrades this isolation to READ_COMMITTED.
- READ_COMMITTED. GemFire XD ensures that ongoing transactional as well as non-transactional (isolation-level NONE) operations never read uncommitted (dirty) data. GemFire XD accomplishes this by maintaining transactional changes in a separate transaction state that is applied to the actual data-store for the table only at commit time. GemFire XD detects only Write-Write conflicts while in READ_COMMITTED isolation level.
REPEATABLE_READ. GemFire XD
supports the REPEATABLE_READ isolation level according to the ANSI SQL
standard. GemFire XD detects both Write-Write conflicts and Read-Write
conflicts while in REPEATABLE_READ isolation level. A transaction that reads
the same row more than once always sees the same column values for the row.
REPEATABLE_READ also guarantees that the underlying committed row in a table
never changes after the first read in a transaction, until the transaction
completes (for example, it commits or aborts).
GemFire XD applies read and write locks to copies of selected data to ensure repeatable reads for the duration of a transaction. GemFire XD does not use range locks, and phantom reads are still possible with this isolation level.
In addition, readers that use the REPEATABLE_READ isolation level are guaranteed to see distributed, atomic commits. This means that if there is a transaction that writes rows and commits over multiple GemFire XD members, then readers either see all of the commit row values across all members of the distributed system (after the commit), or they will see all of before-committed row values across all members. Readers never see some committed rows on one member and before-committed row values on another node (as with READ_COMMITTED transaction isolation). To support this behavior, GemFire XD uses a 2-phase commit protocol for all REPEATABLE_READ transactions that have pending writes. Note that using REAPEATABLE_READ isolation has higher chance of receiving deadlocks because there are much greater overlaps between readers and writers. Deadlocks cause one or both transactions to fail after a timeout period (see gemfire.LOCK_MAX_TIMEOUT).
GemFire XD detects conflicts between two transactions that write on the same row either during the transactions or just before a commit for READ_COMMITTED and REPEATABLE_READ transactions. However, if a REPEATABLE_READ transaction writes on the same row that has been read by another transaction, then GemFire XD always detects such a conflict before the writer commits (in the first phase of the commit). This enables the system to minimize conflicts where reader transactions are short in duration and the transactions complete before the writer starts its commit.Note: REPEATABLE_READ transactions that have only performed reads never receive a conflict. In particular, even if a transaction reads a row after it has already been marked for write by another transaction, it is the writer that sees the conflict at commit time if the reader transaction has not completed by then. For both the write-write and write-read cases, if a reader or writer attempts to lock a row while the commit of another writer transaction on the row is in progress, then the reader waits for the commit to complete. The commit is usually short in duration, so this behavior reduces conflicts and ensures that the wait is finite.
Applications should avoid mixing REPEATABLE_READ and READ_COMMITTED transactions to reduce potential conflicts. If a REPEATABLE_READ transaction is started before a READ_COMMITTED transaction, the REPEATABLE_READ transaction can potentially hold read locks, resulting in a conflict exception with the READ_COMMITTED transaction.
GemFire XD provides the gemfire.LOCK_MAX_TIMEOUT system property that you can use to alter the conflict detection behavior for READ_COMMITTED and REPEATABLE_READ transactions.Note: You must set this system properties to the same value on each data store in your GemFire XD distributed system.