Program guide > Access data with client applications > Programming for transactions
For transactions, you can configure each backing map configuration with one of three lock strategies: pessimistic, optimistic or none. When you are using pessimistic and optimistic locking, eXtreme Scale uses shared (S), upgradeable (U) and exclusive (X) locks to maintain consistency. This locking behavior is most notable when using pessimistic locking, because optimistic locks are not held. Use one of three transaction isolation levels to tune the locking semantics that eXtreme Scale uses to maintain consistency in each cache map: repeatable read, read committed and read uncommitted.
Transaction isolation overview
Transaction isolation defines how the changes that are made by one operation become visible to other concurrent operations.
WebSphere eXtreme Scale supports three transaction isolation levels with which you can further tune the locking semantics that eXtreme Scale uses to maintain consistency in each cache map: repeatable read, read committed and read uncommitted. The transaction isolation level is set on the Session interface using the setTransactionIsolation method. The transaction isolation can be changed any time during the life of the session, if a transaction is not currently in progress.
The product enforces the various transaction isolation semantics by adjusting the way in which shared (S) locks are requested and held. Transaction isolation has no effect on maps configured to use the optimistic or none locking strategies or when upgradeable (U) locks are acquired.
Repeatable read with pessimistic locking
The repeatable read transaction isolation level is the default. This isolation level prevents dirty reads and non-repeatable reads, but does not prevent phantom reads. A dirty read is a read operation that occurs on data that has been modified by a transaction but has not been committed. A non-repeatable read might occur when read locks are not acquired when performing a read operation. A phantom read can occur when two identical read operations are performed, but two different sets of results are returned because an update has occurred on the data between the read operations. The product achieve a repeatable read by holding onto any S locks until the transaction that owns the lock completes. Because an X lock is not granted until all S locks are released, all transactions holding the S lock are guaranteed to see the same value when re-read.
map = session.getMap("Order"); session.setTransactionIsolation(Session.TRANSACTION_REPEATABLE_READ); session.begin(); // An S lock is requested and held and the value is copied into // the transactional cache. Order order = (Order) map.get("100"); // The entry is evicted from the transactional cache. map.invalidate("100", false); // The same value is requested again. It already holds the // lock, so the same value is retrieved and copied into the // transactional cache. Order order2 (Order) = map.get("100"); // All locks are released after the transaction is synchronized // with cache map. session.commit();
Phantom reads are possible when you are using queries or indexes because locks are not acquired for ranges of data, only for the cache entries that match the index or query criteria. For example:
session1.setTransactionIsolation(Session.TRANSACTION_REPEATABLE_READ); session1.begin(); // A query is run which selects a range of values. ObjectQuery query = session1.createObjectQuery ("SELECT o FROM Order o WHERE o.itemName='Widget'"); // In this case, only one order matches the query filter. // The order has a key of "100". // The query engine automatically acquires an S lock for Order "100". Iterator result = query.getResultIterator(); // A second transaction inserts an order that also matches the query. Map orderMap = session2.getMap("Order"); orderMap.insert("101", new Order("101", "Widget")); // When the query runs again in the current transaction, the // new order is visible and will return both Orders "100" and "101". result = query.getResultIterator(); // All locks are released after the transaction is synchronized // with cache map. session.commit();
Read committed with pessimistic locking
The read committed transaction isolation level can be used with eXtreme Scale, which prevents dirty reads, but does not prevent non-repeatable reads or phantom reads, so eXtreme Scale continues to use S locks to read data from the cache map, but immediately releases the locks.
map1 = session1.getMap("Order"); session1.setTransactionIsolation(Session.TRANSACTION_READ_COMMITTED); session1.begin(); // An S lock is requested but immediately released and //the value is copied into the transactional cache. Order order = (Order) map1.get("100"); // The entry is evicted from the transactional cache. map1.invalidate("100", false); // A second transaction updates the same order. // It acquires a U lock, updates the value, and commits. // The ObjectGrid successfully acquires the X lock during // commit since the first transaction is using read // committed isolation. Map orderMap2 = session2.getMap("Order"); session2.begin(); order2 = (Order) orderMap2.getForUpdate("100"); order2.quantity=2; orderMap2.update("100", order2); session2.commit(); // The same value is requested again. This time, they // want to update the value, but it now reflects // the new value Order order1Copy (Order) = map1.getForUpdate("100");
Read uncommitted with pessimistic locking
The read uncommitted transaction isolation level can be used with eXtreme Scale, which is a level that allows dirty reads, non-repeatable reads and phantom reads.
Parent topic:Program for transactions
Transaction processing overview
Optimistic collision exception
Run parallel business logic on the data grid (DataGrid API)