- Verify.verify(wasOpen);
-
- if (lastTx != null) {
- final boolean success = CURRENT_UPDATER.compareAndSet(this, null, transaction);
- Verify.verify(success);
- if (lastTx == null) {
- // Dispatch after requeue
- processCurrentTransaction();
+ Preconditions.checkState(wasOpen, "Attempted to submit non-open transaction %s", transaction);
+
+ if (lastTx == null) {
+ // No transaction outstanding, we need to submit it now
+ synchronized (this) {
+ submitTransaction(transaction);
+ }
+
+ return;
+ }
+
+ // There is a potentially-racing submitted transaction. Publish the new one, which may end up being
+ // picked up by processNextTransaction.
+ final boolean success = CURRENT_UPDATER.compareAndSet(this, null, transaction);
+ Verify.verify(success);
+
+ // Now a quick check: if the racing transaction completed in between, it may have missed the current
+ // transaction, hence we need to re-check
+ if (lastTx == null) {
+ submitCurrentTransaction();
+ }
+ }
+
+ private void submitCurrentTransaction() {
+ final ShardedDOMDataTreeWriteTransaction current = currentTx;
+ if (current != null) {
+ synchronized (this) {
+ if (CURRENT_UPDATER.compareAndSet(this, current, null)) {
+ submitTransaction(current);
+ }