public TransactionSource getSource() { TransactionReference tx = transactions.get(); if (tx != null) { return tx.getSource(); } return null; }
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(); } } }