public ModificationQueue finishTx() { final TransactionReference tx = transactions.get(); ModificationQueue modificationQueue = null; if (tx != null) { if (tx.isToplevel()) { modificationQueue = queues.get(); final Set<String> synchronizationKeys = modificationQueue.getSynchronizationKeys(); // cleanup queues.remove(); buffers.remove(); currentCommand.remove(); transactions.remove(); try { tx.close(); } catch (Throwable t) { t.printStackTrace(); } finally { // release semaphores as the transaction is now finished semaphore.release(synchronizationKeys); // careful: this can be null } } else { tx.end(); } } return modificationQueue; }
public void commitTx(final boolean doValidation) throws FrameworkException { final TransactionReference tx = transactions.get(); if (tx != null && tx.isToplevel()) { final ModificationQueue modificationQueue = queues.get(); final ErrorBuffer errorBuffer = buffers.get(); // 0.5: let transaction listeners examine (and prevent?) commit for (final StructrTransactionListener listener : listeners) { listener.beforeCommit( securityContext, modificationQueue.getModificationEvents(), tx.getSource()); } // 1. do inner callbacks (may cause transaction to fail) if (doValidation) { if (!modificationQueue.doInnerCallbacks(securityContext, errorBuffer)) { tx.failure(); throw new FrameworkException( 422, "Unable to commit transaction, validation failed", errorBuffer); } // 1.5: execute validatable post-transaction action if (!modificationQueue.doPostProcessing(securityContext, errorBuffer)) { tx.failure(); throw new FrameworkException( 422, "Unable to commit transaction, transaction post processing failed", errorBuffer); } } // 2. fetch all types of entities modified in this tx Set<String> synchronizationKeys = modificationQueue.getSynchronizationKeys(); // we need to protect the validation and indexing part of every transaction // from being entered multiple times in the presence of validators // 3. acquire semaphores for each modified type try { semaphore.acquire(synchronizationKeys); } catch (InterruptedException iex) { return; } // finally, do validation under the protection of the semaphores for each type if (!modificationQueue.doValidation(securityContext, errorBuffer, doValidation)) { tx.failure(); // create error throw new FrameworkException( 422, "Unable to commit transaction, validation failed", errorBuffer); } try { tx.success(); } catch (Throwable t) { t.printStackTrace(); } } }