Invoking the flush method on the ObjectMap interface before a commit can introduce additional lock ordering considerations. The flush method is typically used to force changes that are made to the map out to the backend through the Loader plug-in.
Session sess = ...;
ObjectMap person = sess.getMap("PERSON");
boolean activeTran = false;
try
{
sess.begin();
activeTran = true;
Person p = (IPerson)person.get("Lynn");
p.setAge( p.getAge() + 1 );
person.put( "Lynn", p );
person.flush();
...
p = (IPerson)person.get("Tom");
p.setAge( p.getAge() + 1 );
sess.commit();
activeTran = false;
}
finally
{
if ( activeTran ) sess.rollback();
}
X lock is granted to transaction 1 for "Lynn" when flush is executed.
X lock is granted to transaction 2 for "Tom" when flush is executed..
X lock requested by transaction 1 for "Tom" during commit processing.
(Transaction 1 blocks waiting for lock owned by transaction 2.)
X lock requested by transaction 2 for "Lynn" during commit processing.
(Transaction 2 blocks waiting for lock owned by transaction 1.)
This example demonstrates that the use of the flush method can cause a deadlock to occur in the database rather than in WebSphere eXtreme Scale Client. This deadlock example can occur regardless of what lock strategy is used. The application must take care to prevent this kind of deadlock from occurring when it is using the flush method and when a Loader is plugged into the BackingMap. The preceding example also illustrates another reason why WebSphere eXtreme Scale Client has a lock wait timeout mechanism. A transaction that is waiting for a database lock might be waiting while it owns an WebSphere eXtreme Scale Client map entry lock. Problems at database level can cause excessive wait times for an WebSphere eXtreme Scale Client lock mode and result in a LockTimeoutException exception.