+ createTransactionContext(failure, response);
+ }
+
+ private void createTransactionContext(Throwable failure, Object response) {
+ // Mainly checking for state violation here to perform a volatile read of "initialized" to
+ // ensure updates to operationLimter et al are visible to this thread (ie we're doing
+ // "piggy-back" synchronization here).
+ Preconditions.checkState(initialized, "Tx was not propertly initialized.");
+
+ // Create the TransactionContext from the response or failure. Store the new
+ // TransactionContext locally until we've completed invoking the
+ // TransactionOperations. This avoids thread timing issues which could cause
+ // out-of-order TransactionOperations. Eg, on a modification operation, if the
+ // TransactionContext is non-null, then we directly call the TransactionContext.
+ // However, at the same time, the code may be executing the cached
+ // TransactionOperations. So to avoid thus timing, we don't publish the
+ // TransactionContext until after we've executed all cached TransactionOperations.
+ TransactionContext localTransactionContext;
+ if(failure != null) {
+ LOG.debug("Tx {} Creating NoOpTransaction because of error", getIdentifier(), failure);
+
+ localTransactionContext = new NoOpTransactionContext(failure, getIdentifier(), operationLimiter);
+ } else if (response.getClass().equals(CreateTransactionReply.SERIALIZABLE_CLASS)) {
+ localTransactionContext = createValidTransactionContext(
+ CreateTransactionReply.fromSerializable(response));