TransactionContextImpl(TransactionManagerServiceImpl transactionManagerService, NodeEngineImpl nodeEngine, TransactionOptions options, String ownerUuid, boolean originatedFromClient) { this.nodeEngine = nodeEngine; this.transaction = new TransactionImpl(transactionManagerService, nodeEngine, options, ownerUuid, originatedFromClient); }
@Override public void beginTransaction() { transaction.begin(); }
@Override public void commitTransaction() throws TransactionException { if (transaction.requiresPrepare()) { transaction.prepare(); } transaction.commit(); }
@Override public void prepare() throws TransactionException { if (state != ACTIVE) { throw new TransactionNotActiveException("Transaction is not active"); } checkThread(); checkTimeout(); try { createBackupLogs(); state = PREPARING; List<Future> futures = transactionLog.prepare(nodeEngine); waitUntilAllRespondedWithDeadline(futures, timeoutMillis, MILLISECONDS, RETHROW_TRANSACTION_EXCEPTION); state = PREPARED; replicateTxnLog(); } catch (Throwable e) { throw rethrow(e, TransactionException.class); } }
@Override public void rollback() throws IllegalStateException { try { if (state == NO_TXN || state == ROLLED_BACK) { throw new IllegalStateException("Transaction is not active"); } checkThread(); state = ROLLING_BACK; try { //TODO: Do we need both a purge and rollback? rollbackBackupLogs(); List<Future> futures = transactionLog.rollback(nodeEngine); waitWithDeadline(futures, Long.MAX_VALUE, MILLISECONDS, rollbackExceptionHandler); purgeBackupLogs(); } catch (Throwable e) { throw rethrow(e); } finally { state = ROLLED_BACK; transactionManagerService.rollbackCount.inc(); } } finally { setThreadFlag(null); } }
checkThread(); checkTimeout(); try { state = COMMITTING; throw rethrow(e, TransactionException.class); } finally { purgeBackupLogs(); setThreadFlag(null);
log.timeoutMillis, log.startTime, log.callerUuid); } else { tx = new TransactionImpl(this, nodeEngine, txnId, log.records, log.timeoutMillis, log.startTime, log.callerUuid); tx.commit(); } catch (Throwable e) { logger.warning("Error during committing from tx backup!", e); tx.rollback(); } catch (Throwable e) { logger.warning("Error during rolling-back from tx backup!", e);
private void replicateTxnLog() { if (skipBackupLogReplication()) { return; } OperationService operationService = nodeEngine.getOperationService(); ClusterService clusterService = nodeEngine.getClusterService(); List<Future> futures = new ArrayList<Future>(backupAddresses.length); for (Address backupAddress : backupAddresses) { if (clusterService.getMember(backupAddress) != null) { Operation op = createReplicateTxBackupLogOperation(); Future f = operationService.invokeOnTarget(SERVICE_NAME, op, backupAddress); futures.add(f); } } waitWithDeadline(futures, timeoutMillis, MILLISECONDS, replicationTxExceptionHandler); }
TransactionImpl(TransactionManagerServiceImpl transactionManagerService, NodeEngine nodeEngine, String txnId, List<TransactionLogRecord> transactionLog, long timeoutMillis, long startTime, String txOwnerUuid) { this.transactionLog = new TransactionLog(transactionLog); this.transactionManagerService = transactionManagerService; this.nodeEngine = nodeEngine; this.txnId = txnId; this.timeoutMillis = timeoutMillis; this.startTime = startTime; this.durability = 0; this.transactionType = TWO_PHASE; this.state = PREPARED; this.txOwnerUuid = txOwnerUuid; this.checkThreadAccess = false; this.logger = nodeEngine.getLogger(getClass()); this.rollbackExceptionHandler = logAllExceptions(logger, "Error during rollback!", Level.FINEST); this.rollbackTxExceptionHandler = logAllExceptions(logger, "Error during tx rollback backup!", Level.FINEST); this.replicationTxExceptionHandler = createReplicationTxExceptionHandler(logger); }
@Override public void add(TransactionLogRecord record) { if (state != Transaction.State.ACTIVE) { throw new TransactionNotActiveException("Transaction is not active!"); } checkThread(); transactionLog.add(record); }
private void forceCreateBackupLogs() { backupLogsCreated = true; OperationService operationService = nodeEngine.getOperationService(); List<Future> futures = new ArrayList<Future>(backupAddresses.length); for (Address backupAddress : backupAddresses) { if (nodeEngine.getClusterService().getMember(backupAddress) != null) { final CreateTxBackupLogOperation op = createCreateTxBackupLogOperation(); Future f = operationService.invokeOnTarget(SERVICE_NAME, op, backupAddress); futures.add(f); } } waitWithDeadline(futures, timeoutMillis, MILLISECONDS, replicationTxExceptionHandler); }
private void purgeBackupLogs() { if (!backupLogsCreated) { return; } OperationService operationService = nodeEngine.getOperationService(); ClusterService clusterService = nodeEngine.getClusterService(); for (Address backupAddress : backupAddresses) { if (clusterService.getMember(backupAddress) != null) { try { operationService.invokeOnTarget(SERVICE_NAME, createPurgeTxBackupLogOperation(), backupAddress); } catch (Throwable e) { logger.warning("Error during purging backups!", e); } } } }
@Override public void prepare() throws TransactionException { if (state != ACTIVE) { throw new TransactionNotActiveException("Transaction is not active"); } checkThread(); checkTimeout(); try { createBackupLogs(); state = PREPARING; List<Future> futures = transactionLog.prepare(nodeEngine); waitUntilAllRespondedWithDeadline(futures, timeoutMillis, MILLISECONDS, RETHROW_TRANSACTION_EXCEPTION); state = PREPARED; replicateTxnLog(); } catch (Throwable e) { throw rethrow(e, TransactionException.class); } }
@Override public void rollback() throws IllegalStateException { try { if (state == NO_TXN || state == ROLLED_BACK) { throw new IllegalStateException("Transaction is not active"); } checkThread(); state = ROLLING_BACK; try { //TODO: Do we need both a purge and rollback? rollbackBackupLogs(); List<Future> futures = transactionLog.rollback(nodeEngine); waitWithDeadline(futures, Long.MAX_VALUE, MILLISECONDS, rollbackExceptionHandler); purgeBackupLogs(); } catch (Throwable e) { throw rethrow(e); } finally { state = ROLLED_BACK; transactionManagerService.rollbackCount.inc(); } } finally { setThreadFlag(null); } }
checkThread(); checkTimeout(); try { state = COMMITTING; throw rethrow(e, TransactionException.class); } finally { purgeBackupLogs(); setThreadFlag(null);
log.timeoutMillis, log.startTime, log.callerUuid); } else { tx = new TransactionImpl(this, nodeEngine, txnId, log.records, log.timeoutMillis, log.startTime, log.callerUuid); tx.commit(); } catch (Throwable e) { logger.warning("Error during committing from tx backup!", e); tx.rollback(); } catch (Throwable e) { logger.warning("Error during rolling-back from tx backup!", e);
private void replicateTxnLog() { if (skipBackupLogReplication()) { return; } OperationService operationService = nodeEngine.getOperationService(); ClusterService clusterService = nodeEngine.getClusterService(); List<Future> futures = new ArrayList<Future>(backupAddresses.length); for (Address backupAddress : backupAddresses) { if (clusterService.getMember(backupAddress) != null) { Operation op = createReplicateTxBackupLogOperation(); Future f = operationService.invokeOnTarget(SERVICE_NAME, op, backupAddress); futures.add(f); } } waitWithDeadline(futures, timeoutMillis, MILLISECONDS, replicationTxExceptionHandler); }
TransactionImpl(TransactionManagerServiceImpl transactionManagerService, NodeEngine nodeEngine, String txnId, List<TransactionLogRecord> transactionLog, long timeoutMillis, long startTime, String txOwnerUuid) { this.transactionLog = new TransactionLog(transactionLog); this.transactionManagerService = transactionManagerService; this.nodeEngine = nodeEngine; this.txnId = txnId; this.timeoutMillis = timeoutMillis; this.startTime = startTime; this.durability = 0; this.transactionType = TWO_PHASE; this.state = PREPARED; this.txOwnerUuid = txOwnerUuid; this.checkThreadAccess = false; this.logger = nodeEngine.getLogger(getClass()); this.rollbackExceptionHandler = logAllExceptions(logger, "Error during rollback!", Level.FINEST); this.rollbackTxExceptionHandler = logAllExceptions(logger, "Error during tx rollback backup!", Level.FINEST); this.replicationTxExceptionHandler = createReplicationTxExceptionHandler(logger); }
@Override public void add(TransactionLogRecord record) { if (state != Transaction.State.ACTIVE) { throw new TransactionNotActiveException("Transaction is not active!"); } checkThread(); transactionLog.add(record); }
private void forceCreateBackupLogs() { backupLogsCreated = true; OperationService operationService = nodeEngine.getOperationService(); List<Future> futures = new ArrayList<Future>(backupAddresses.length); for (Address backupAddress : backupAddresses) { if (nodeEngine.getClusterService().getMember(backupAddress) != null) { final CreateTxBackupLogOperation op = createCreateTxBackupLogOperation(); Future f = operationService.invokeOnTarget(SERVICE_NAME, op, backupAddress); futures.add(f); } } waitWithDeadline(futures, timeoutMillis, MILLISECONDS, replicationTxExceptionHandler); }