use of org.apache.ignite.transactions.TransactionState in project ignite by apache.
the class IgniteTxManager method txsPreparedOrCommitted.
/**
* @param nearVer Near version ID.
* @param txNum Number of transactions.
* @param fut Result future.
* @param processedVers Processed versions.
* @return Future for flag indicating if transactions were prepared or committed or {@code null} for success future.
*/
@Nullable
private IgniteInternalFuture<Boolean> txsPreparedOrCommitted(final GridCacheVersion nearVer, int txNum, @Nullable GridFutureAdapter<Boolean> fut, @Nullable Collection<GridCacheVersion> processedVers) {
for (final IgniteInternalTx tx : activeTransactions()) {
if (nearVer.equals(tx.nearXidVersion())) {
IgniteInternalFuture<?> prepFut = tx.currentPrepareFuture();
if (prepFut != null && !prepFut.isDone()) {
if (log.isDebugEnabled())
log.debug("Transaction is preparing (will wait): " + tx);
final GridFutureAdapter<Boolean> fut0 = fut != null ? fut : new GridFutureAdapter<Boolean>();
final int txNum0 = txNum;
final Collection<GridCacheVersion> processedVers0 = processedVers;
prepFut.listen(new CI1<IgniteInternalFuture<?>>() {
@Override
public void apply(IgniteInternalFuture<?> prepFut) {
if (log.isDebugEnabled())
log.debug("Transaction prepare future finished: " + tx);
IgniteInternalFuture<Boolean> fut = txsPreparedOrCommitted(nearVer, txNum0, fut0, processedVers0);
assert fut == fut0;
}
});
return fut0;
}
TransactionState state = tx.state();
if (state == PREPARED || state == COMMITTING || state == COMMITTED) {
if (state == PREPARED)
// Prevents concurrent rollback.
tx.markFinalizing(RECOVERY_FINISH);
if (--txNum == 0) {
if (fut != null)
fut.onDone(true);
return fut;
}
} else {
if (tx.setRollbackOnly() || tx.state() == UNKNOWN) {
tx.rollbackAsync();
if (log.isDebugEnabled())
log.debug("Transaction was not prepared (rolled back): " + tx);
if (fut == null)
fut = new GridFutureAdapter<>();
fut.onDone(false);
return fut;
} else {
if (tx.state() == COMMITTED) {
if (--txNum == 0) {
if (fut != null)
fut.onDone(true);
return fut;
}
} else {
if (log.isDebugEnabled())
log.debug("Transaction is not prepared: " + tx);
if (fut == null)
fut = new GridFutureAdapter<>();
fut.onDone(false);
return fut;
}
}
}
if (processedVers == null)
processedVers = U.newHashSet(txNum);
processedVers.add(tx.xidVersion());
}
}
// if transaction was already committed.
for (Map.Entry<GridCacheVersion, Object> e : completedVersHashMap.entrySet()) {
if (e.getValue().equals(Boolean.FALSE))
continue;
GridCacheVersion ver = e.getKey();
if (processedVers != null && processedVers.contains(ver))
continue;
if (ver instanceof CommittedVersion) {
CommittedVersion commitVer = (CommittedVersion) ver;
if (commitVer.nearVer.equals(nearVer)) {
if (--txNum == 0) {
if (fut != null)
fut.onDone(true);
return fut;
}
}
}
}
if (fut == null)
fut = new GridFutureAdapter<>();
fut.onDone(false);
return fut;
}
Aggregations