Lock thisLock = this.lock.writeLock();
Lock thatLock = that.lock.writeLock();
ChangeSet events1 = null;
ChangeSet events2 = null;
Transaction txn = null;
try {
thisLock.lock();
thatLock.lock();
// Before we start the transaction, apply the pre-save operations to the new and changed nodes below the path ...
final List<NodeKey> savedNodesInOrder = new LinkedList<NodeKey>();
// Before we start the transaction, apply the pre-save operations to the new and changed nodes ...
if (preSaveOperation != null) {
SaveContext saveContext = new BasicSaveContext(context());
for (MutableCachedNode node : this.changedNodes.values()) {
if (node == REMOVED || !toBeSaved.contains(node.getKey())) {
continue;
}
checkNodeNotRemovedByAnotherTransaction(node);
preSaveOperation.process(node, saveContext);
savedNodesInOrder.add(node.getKey());
}
}
final int numNodes = savedNodesInOrder.size() + that.changedNodesInOrder.size();
int repeat = txns.isCurrentlyInTransaction() ? 1 : MAX_REPEAT_FOR_LOCK_ACQUISITION_TIMEOUT;
while (--repeat >= 0) {
try {
// Start a ModeShape transaction (which may be a part of a larger JTA transaction) ...
txn = txns.begin();
assert txn != null;
try {
// Lock the nodes in Infinispan
WorkspaceCache thisPersistedCache = lockNodes(savedNodesInOrder);
WorkspaceCache thatPersistedCache = that.lockNodes(that.changedNodesInOrder);
// process after locking
// Before we start the transaction, apply the pre-save operations to the new and changed nodes ...
if (preSaveOperation != null) {
SaveContext saveContext = new BasicSaveContext(context());
for (MutableCachedNode node : this.changedNodes.values()) {
if (node == REMOVED || !toBeSaved.contains(node.getKey())) {
continue;
}
preSaveOperation.processAfterLocking(node, saveContext, thisPersistedCache);
}
}
// Now persist the changes ...
logChangesBeingSaved(savedNodesInOrder, this.changedNodes, that.changedNodesInOrder, that.changedNodes);
events1 = persistChanges(savedNodesInOrder, thisPersistedCache);
// If there are any binary changes, add a function which will update the binary store
if (events1.hasBinaryChanges()) {
txn.uponCommit(binaryUsageUpdateFunction(events1.usedBinaries(), events1.unusedBinaries()));
}
events2 = that.persistChanges(that.changedNodesInOrder, thatPersistedCache);
if (events2.hasBinaryChanges()) {
txn.uponCommit(binaryUsageUpdateFunction(events2.usedBinaries(), events2.unusedBinaries()));
}
} catch (org.infinispan.util.concurrent.TimeoutException e) {
txn.rollback();
if (repeat <= 0) throw new TimeoutException(e.getMessage(), e);
--repeat;
Thread.sleep(PAUSE_TIME_BEFORE_REPEAT_FOR_LOCK_ACQUISITION_TIMEOUT);
continue;
} catch (IllegalStateException err) {
// Not associated with a txn??
throw new SystemFailureException(err);
} catch (IllegalArgumentException err) {
// Not associated with a txn??
throw new SystemFailureException(err);
} catch (Exception e) {
// Some error occurred (likely within our code) ...
txn.rollback();
throw e;
}
LOGGER.debug("Altered {0} node(s)", numNodes);
// Commit the transaction ...
txn.commit();
clearState(savedNodesInOrder);
that.clearState();
} catch (NotSupportedException err) {