MODE-1746 Use explicit locks to prevent deadlocks

Added a test method to the ConcurrentWriteTest that replicates how separate threads can deadlock while attempting to update several nodes.

Added quite a few debug and trace logging calls to help investigate transaction-related operations.

Added explicit locking to prevent deadlocks. Locks for all modified nodes are now requested at the beginning of the transaction (rather than incrementally as needed to apply the changes in the same order as modified by the session). The locks will either all be acquired or none of them will be acquired, allowing the "save()" operation to retry to acquire the locks one additional time. If the locks still cannot be acquired (or if Infinispan throws a TimeoutException because the locks could not be acquired after the configured period of time), ModeShape will rollback the transaction.

The WritableSessionCache will attempts to retry the transaction if and only if the save() operation started the transaction. If there was already an existing transaction, ModeShape cannot restart it and therefore it must fail.

In all cases, should locks not be acquired during the "Session.save()" call, an org.modeshape.jcr.TimeoutException will be thrown. Client applications can catch this and simply retry calling "Session.save()" again as many times as desired.

Under configurations that experience a high amount of concurrent operations on the same set of nodes, the Infinispan configuration should probably use deadlock detection.