use of org.structr.core.StructrTransactionListener in project structr by structr.
the class TransactionCommand method commitTx.
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 (!modificationQueue.doInnerCallbacks(securityContext, errorBuffer)) {
tx.failure();
throw new FrameworkException(422, "Unable to commit transaction, validation failed", errorBuffer);
}
// 2. fetch all types of entities modified in this tx
Set<String> synchronizationKeys = modificationQueue.getSynchronizationKeys();
// 3. acquire semaphores for each modified type
try {
semaphore.acquire(synchronizationKeys);
} catch (InterruptedException iex) {
return;
}
// do validation under the protection of the semaphores for each type
if (doValidation && !modificationQueue.doValidation(securityContext, errorBuffer, doValidation)) {
tx.failure();
// create error
throw new FrameworkException(422, "Unable to commit transaction, validation failed", errorBuffer);
}
// finally: 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);
}
try {
tx.success();
} catch (Throwable t) {
logger.error("Unable to commit transaction", t);
}
}
}
use of org.structr.core.StructrTransactionListener in project structr by structr.
the class Tx method close.
@Override
public void close() throws FrameworkException {
final ModificationQueue modificationQueue = cmd.finishTx();
if (success && guard.compareAndSet(false, true)) {
boolean retry = true;
while (retry) {
retry = false;
// experimental
try (final Tx tx = begin()) {
if (doCallbacks && modificationQueue != null) {
modificationQueue.doOuterCallbacks(securityContext);
// notify listeners if desired, and allow this setting to be overriden locally AND remotely
if ((securityContext == null) ? doNotifications : doNotifications && securityContext.doTransactionNotifications()) {
final Collection<ModificationEvent> modificationEvents = modificationQueue.getModificationEvents();
for (final StructrTransactionListener listener : TransactionCommand.getTransactionListeners()) {
listener.afterCommit(securityContext, modificationEvents, cmd.getSource());
}
}
modificationQueue.updateChangelog();
modificationQueue.clear();
}
tx.success();
} catch (RetryException rex) {
retry = true;
}
}
guard.set(false);
}
}
Aggregations