Summary: This page is describing the ReadModifiers enum parameter used in the Read ReadIfExist ReadMultiple Count operations. ExclusiveReadLock, ReadCommitted, DirtyRead, and RepeatableRead modifiers.

Overview

Using the ReadModifier a user can dramatically change the way the same operation will result in terms of performance and returned value, in certain situations.
Understanding the different behavior and tradeoffs between the ReadModifier is important on system that heavily uses transactions or is looking for performance fine tuning.
The ReadModifiers enum set of modifiers are represented as integers with distinct bit positions representing different modifiers.

Four types of modifiers can be used:

  • RepeatableRead – default modifier
  • DirtyRead
  • ReadCommitted
  • ExclusiveReadLock

RepeatableRead, DirtyRead, and ReadCommitted are mutually exclusive (i.e. can't be used together). ExclusiveReadLock can be joined with any of them.

The modifiers can be set either at the proxy level – IReadOnlySpaceProxy.ReadModifiers, or at the operation level (e.g. using one of Read/ReadIfExist/ReadMultiple/Count methods with a modifiers parameter).

Repeatable Read

RepeatableRead is the default modifier.

The RepeatableRead isolation level allows a transaction to acquire read locks on all rows of data it returns to an application, and write locks on all rows of data it inserts, updates, or deletes. By using the RepeatableRead isolation level, SELECT SQL statements issued multiple times within the same transaction always yield the same result. A transaction using the RepeatableRead isolation level can retrieve and manipulate the same rows of data as many times as needed until it completes its task. However, no other transaction can insert, update, or delete a row of data that can affect the result table being accessed, until the isolating transaction releases its locks. That is, when the isolating transaction is either committed or rolled back.

Transactions using the RepeatableRead isolation level wait until rows of data that are write-locked by other transactions are unlocked before they acquire their own locks. This prevents them from reading "dirty" data. In addition, because other transactions cannot update or delete rows of data that are locked by a transaction using the RepeatableRead isolation level, non-repeatable read situations are avoided.

Dirty Read

The visibility of Entries for read operations is defined as follows: A read operation performed under a null (no transaction) transaction can only access Entries that are not write-locked by non-null transactions. In other words, Entries that were written or taken by active transactions (transactions that have not been committed or rolled back) are not visible to the user performing a read operation.

Sometimes it is desirable for non-transactional read operations to have full visibility of the Entries in the space. The DirtyRead modifier, once set, enables Read/ReadIfExists/ReadMultiple/count operations under a null transaction to have this complete visibility.

Dirty read can also be set in the level of the whole space, using the space schema. For more details, refer to the Dirty Read - Space Schema section.

Code Example

// write something under txn X and commit, making it publicly visible
ijspace.write( something, txnX, Lease.FOREVER);
txnX.commit();

// update this something with a new one under a different txn Y
ijspace.update( newSomething, txnY, Lease.FOREVER, IJSpace.NO_WAIT);

// all read operations (read, readIfExists, readMultiple, count) return the  
// version of the object before txnY was committed (newSomething).
// operations can be performed with a new txn Z or a null txn
ijspace.read( tmpl, null, ReadModifiers.DirtyRead);

// Note: using the same txn (txn Y) will return matches that are visible under the transaction

Read Committed

The ReadCommitted modifier enables a read-committed isolation level in read operations.

Read-committed is the isolation-level in which a read operation (under a transaction or a null transaction) can not see changes made by other transactions, until those transactions are committed. At this level of isolation, dirty-reads are not possible, but unrepeatable-reads and phantoms might occur.

Read-committed is the default isolation level in database systems. This isolation level means that the read operations return the Entry that are currently committed, regardless of the fact that these Entries might be updated (with a newer version) or taken under an uncommitted transaction. This is opposed to the default space isolation-level (derived from the JavaSpaces specification), which is repeatable-read.

The read-committed isolation level is useful for the local cache, local view, and GSIterators, which performs readMultiple and keep their current status by registrating notify templates.

The ReadCommitted modifier is provided at the proxy level and the read API level. It is relevant for read, readIfExists, readMultiple, and count.

ReadCommitted and DirtyRead are mutually-exclusive. An Entry under an (uncommitted) updating transaction or under a taking (unrolled) transaction returns the original (committed) value unless the operation is under the same transaction as the locking one.

If the read operation is under a transaction, there is no need to "enlist" the Entry in the transaction (unless its already enlisted).

readIfExists has less Entries to wait for, unless these are new Entries under an uncommitted transaction.

Locking and Blocking Rules

The ReadCommitted blocking scheme (ReadCommitted=RC):

Operation A/Operation B Update under transaction Y Take under transaction Y Read under transaction Y Update, null transaction Take, null transaction Read, null transaction Exclusive Read Lock
Update under transaction X Blocked Blocked
Blocked
Blocked
Blocked
Blocked (unless in DirtyRead)
Blocked
Take under transaction X Blocked
Blocked
Blocked
Blocked
Blocked
Blocked
Blocked
Read under transaction X Blocked
Blocked
Allowed
Blocked
Blocked
Allowed
Blocked
Update, null transaction Allowed
Allowed
Allowed
Allowed
Allowed
Allowed
Allowed
Take, null transaction Allowed
Allowed
Allowed
Allowed
Allowed
Allowed
Allowed
Read, null transaction Allowed
Allowed
Allowed
Allowed
Allowed
Allowed
Allowed
Exclusive Read Lock Blocked
Blocked
Blocked
Allowed
Allowed
Allowed
Blocked
Read -RC transaction X or null Allowed
Allowed
Allowed
Allowed
Allowed
Allowed
Allowed

Refer to the Space Locking and Blocking section for GigaSpaces general locking and blocking rules.

  • To read the original state of an entry that is locked under a transaction (take or update) you should use ReadCommitted mode.
  • To read the current state of an entry that is locked under transaction (take or update) should use Dirty Read mode.
  • Dirty read (without transaction) does not blocks transactional take operation.

Code Example

// write something under txn X and commit, making it publicly visible
ijspace.write( something, txnX, Lease.FOREVER);
txnX.commit();

// update this something with a new one under a different txn Y
ijspace.update( newSomething, txnY, Lease.FOREVER, IJSpace.NO_WAIT);

// all read operations (read, readIfExists, readMultiple, count) return the last publicly visible match.
// operations can be performed with a new txn Z or a null txn
ijspace.read( tmpl, txnZ, ReadModifiers.ReadCommitted);

// Note: using the same txn (txn Y) will return matches that are visible under the transaction

Exclusive Read Lock

The Exclusive Read Lock is similar to select for update SQL for RDBMS, or update lock with ODBMS.

In the JavaSpaces specification, a read under a transaction does not allow other users to modify the Entry, but it does allow two readers or more to read the same Entry under different transactions. To allow a user to block other users from reading an object, a read using exclusive read lock mode with a transaction should be performed.

The following methods support exclusive read lock when used with a transaction:

  • read()
  • readIfExists()
  • readMultiple()

The exclusive read lock is supported in a clustered environment when using the Jini Transaction Manager.

Code Example

IJSpace space = (IJSpace) SpaceFinder.find("jini://*/*/mySpace");
space.setReadModifiers(ReadModifiers.ExclusiveReadLock);
// this will allow all read operations with this proxy to use Exclusive Read Lock mode
Lock lock = new Lock();
lock.key = new Integer(1);
lock.data = "my data";
space.write(lock, null, Lease.FOREVER);
LocalTransactionManager trManager = (LocalTransactionManager)LocalTransactionManager
		.getInstance(space);

Transaction.Created tCreated1 = TransactionFactory.create(trManager, 1000 * 60);
ServerTransaction txn1 = (ServerTransaction)tCreated1.transaction;
Lock lock_template1 = new Lock();
lock_template1.key = new Integer(1);
Lock lock1 = (Lock) space.read(lock_template1, txn1, 1000);
If (lock1!= null)
	System.out.println("Transaction " + txn1.id + " Got exclusive Read Lock on Entry:"
		+ lock1.__getEntryInfo().m_UID);
GigaSpaces.com - Legal Notice - 3rd Party Licenses - Site Map - API Docs - Forum - Downloads - Blog - White Papers - Contact Tech Writing - Gen. by Atlassian Confluence