/** * Return the timestamp of the oldest in-flight transaction. * @return the timestamp or Long.MIN_VALUE if there is no in-flight transaction. */ public long getOldestInFlightTransactionTimestamp() { if (inFlightTransactions.isEmpty()) { if (log.isDebugEnabled()) log.debug("oldest in-flight transaction's timestamp: " + Long.MIN_VALUE); return Long.MIN_VALUE; } long oldestTimestamp = Long.MAX_VALUE; for (Map.Entry<Uid, BitronixTransaction> entry : inFlightTransactions.entrySet()) { Uid gtrid = entry.getKey(); long currentTimestamp = gtrid.extractTimestamp(); if (currentTimestamp < oldestTimestamp) oldestTimestamp = currentTimestamp; } if (log.isDebugEnabled()) log.debug("oldest in-flight transaction's timestamp: " + oldestTimestamp); return oldestTimestamp; }
/** * Return the timestamp of the oldest in-flight transaction. * @return the timestamp or Long.MIN_VALUE if there is no in-flight transaction. */ public long getOldestInFlightTransactionTimestamp() { if (inFlightTransactions.isEmpty()) { if (log.isDebugEnabled()) log.debug("oldest in-flight transaction's timestamp: " + Long.MIN_VALUE); return Long.MIN_VALUE; } long oldestTimestamp = Long.MAX_VALUE; for (Map.Entry<Uid, BitronixTransaction> entry : inFlightTransactions.entrySet()) { Uid gtrid = entry.getKey(); long currentTimestamp = gtrid.extractTimestamp(); if (currentTimestamp < oldestTimestamp) oldestTimestamp = currentTimestamp; } if (log.isDebugEnabled()) log.debug("oldest in-flight transaction's timestamp: " + oldestTimestamp); return oldestTimestamp; }
/** * Return the timestamp of the oldest in-flight transaction. * @return the timestamp or Long.MIN_VALUE if there is no in-flight transaction. */ public long getOldestInFlightTransactionTimestamp() { try { // The inFlightTransactions map is sorted by timestamp, so the first transaction is always the oldest BitronixTransaction oldestTransaction = inFlightTransactions.firstKey(); long oldestTimestamp = oldestTransaction.getResourceManager().getGtrid().extractTimestamp(); if (log.isDebugEnabled()) { log.debug("oldest in-flight transaction's timestamp: " + oldestTimestamp); } return oldestTimestamp; } catch (NoSuchElementException e) { if (log.isDebugEnabled()) { log.debug("oldest in-flight transaction's timestamp: " + Long.MIN_VALUE); } return Long.MIN_VALUE; } }
/** * Return the timestamp of the oldest in-flight transaction. * @return the timestamp or Long.MIN_VALUE if there is no in-flight transaction. */ public long getOldestInFlightTransactionTimestamp() { try { // The inFlightTransactions map is sorted by timestamp, so the first transaction is always the oldest BitronixTransaction oldestTransaction = inFlightTransactions.firstKey(); long oldestTimestamp = oldestTransaction.getResourceManager().getGtrid().extractTimestamp(); if (log.isDebugEnabled()) { log.debug("oldest in-flight transaction's timestamp: " + oldestTimestamp); } return oldestTimestamp; } catch (NoSuchElementException e) { if (log.isDebugEnabled()) { log.debug("oldest in-flight transaction's timestamp: " + Long.MIN_VALUE); } return Long.MIN_VALUE; } }
/** * Rollback aborted branches of the resource specified by uniqueName. * Step 3. * @param oldestTransactionTimestamp the timestamp of the oldest transaction still in-flight. * @param uniqueName the unique name of the resource on which to rollback branches. * @param recoveredXids a set of {@link BitronixXid} recovered on the reource. * @param committedGtrids a set of {@link Uid}s already committed on the resource. * @return the rolled back branches count. * @throws RecoveryException if an error preventing recovery happened. */ private int rollbackAbortedBranchesOfResource(long oldestTransactionTimestamp, String uniqueName, Set<BitronixXid> recoveredXids, Set<Uid> committedGtrids) throws RecoveryException { int abortedCount = 0; for (BitronixXid recoveredXid : recoveredXids) { if (committedGtrids.contains(recoveredXid.getGlobalTransactionIdUid())) { if (log.isDebugEnabled()) log.debug("XID has been committed, skipping rollback: " + recoveredXid + " on " + uniqueName); continue; } long txTimestamp = recoveredXid.getGlobalTransactionIdUid().extractTimestamp(); if (log.isDebugEnabled()) log.debug("recovered XID timestamp: " + txTimestamp + " - oldest in-flight TX timestamp: " + oldestTransactionTimestamp); if (txTimestamp >= oldestTransactionTimestamp) { if (log.isDebugEnabled()) log.debug("skipping XID of in-flight transaction: " + recoveredXid); continue; } if (log.isDebugEnabled()) log.debug("rolling back in-doubt branch with XID " + recoveredXid + " on " + uniqueName); boolean success = rollback(uniqueName, recoveredXid); if (success) abortedCount++; } return abortedCount; }
/** * Rollback aborted branches of the resource specified by uniqueName. * Step 3. * @param oldestTransactionTimestamp the timestamp of the oldest transaction still in-flight. * @param uniqueName the unique name of the resource on which to rollback branches. * @param recoveredXids a set of {@link BitronixXid} recovered on the reource. * @param committedGtrids a set of {@link Uid}s already committed on the resource. * @return the rolled back branches count. * @throws RecoveryException if an error preventing recovery happened. */ private int rollbackAbortedBranchesOfResource(long oldestTransactionTimestamp, String uniqueName, Set<BitronixXid> recoveredXids, Set<Uid> committedGtrids) throws RecoveryException { int abortedCount = 0; for (BitronixXid recoveredXid : recoveredXids) { if (committedGtrids.contains(recoveredXid.getGlobalTransactionIdUid())) { if (log.isDebugEnabled()) log.debug("XID has been committed, skipping rollback: " + recoveredXid + " on " + uniqueName); continue; } long txTimestamp = recoveredXid.getGlobalTransactionIdUid().extractTimestamp(); if (log.isDebugEnabled()) log.debug("recovered XID timestamp: " + txTimestamp + " - oldest in-flight TX timestamp: " + oldestTransactionTimestamp); if (txTimestamp >= oldestTransactionTimestamp) { if (log.isDebugEnabled()) log.debug("skipping XID of in-flight transaction: " + recoveredXid); continue; } if (log.isDebugEnabled()) log.debug("rolling back in-doubt branch with XID " + recoveredXid + " on " + uniqueName); boolean success = rollback(uniqueName, recoveredXid); if (success) abortedCount++; } return abortedCount; }
/** * Rollback aborted branches of the resource specified by uniqueName. * Step 3. * @param oldestTransactionTimestamp the timestamp of the oldest transaction still in-flight. * @param uniqueName the unique name of the resource on which to rollback branches. * @param recoveredXids a set of {@link BitronixXid} recovered on the reource. * @param committedGtrids a set of {@link Uid}s already committed on the resource. * @return the rolled back branches count. * @throws RecoveryException if an error preventing recovery happened. */ private int rollbackAbortedBranchesOfResource(long oldestTransactionTimestamp, String uniqueName, Set<BitronixXid> recoveredXids, Set<Uid> committedGtrids) throws RecoveryException { int abortedCount = 0; for (BitronixXid recoveredXid : recoveredXids) { if (committedGtrids.contains(recoveredXid.getGlobalTransactionIdUid())) { if (log.isDebugEnabled()) { log.debug("XID has been committed, skipping rollback: " + recoveredXid + " on " + uniqueName); } continue; } long txTimestamp = recoveredXid.getGlobalTransactionIdUid().extractTimestamp(); if (log.isDebugEnabled()) { log.debug("recovered XID timestamp: " + txTimestamp + " - oldest in-flight TX timestamp: " + oldestTransactionTimestamp); } if (txTimestamp >= oldestTransactionTimestamp) { if (log.isDebugEnabled()) { log.debug("skipping XID of in-flight transaction: " + recoveredXid); } continue; } if (log.isDebugEnabled()) { log.debug("rolling back in-doubt branch with XID " + recoveredXid + " on " + uniqueName); } boolean success = rollback(uniqueName, recoveredXid); if (success) abortedCount++; } return abortedCount; }
/** * Rollback aborted branches of the resource specified by uniqueName. * Step 3. * @param oldestTransactionTimestamp the timestamp of the oldest transaction still in-flight. * @param uniqueName the unique name of the resource on which to rollback branches. * @param recoveredXids a set of {@link BitronixXid} recovered on the reource. * @param committedGtrids a set of {@link Uid}s already committed on the resource. * @return the rolled back branches count. * @throws RecoveryException if an error preventing recovery happened. */ private int rollbackAbortedBranchesOfResource(long oldestTransactionTimestamp, String uniqueName, Set<BitronixXid> recoveredXids, Set<Uid> committedGtrids) throws RecoveryException { int abortedCount = 0; for (BitronixXid recoveredXid : recoveredXids) { if (committedGtrids.contains(recoveredXid.getGlobalTransactionIdUid())) { if (log.isDebugEnabled()) { log.debug("XID has been committed, skipping rollback: " + recoveredXid + " on " + uniqueName); } continue; } long txTimestamp = recoveredXid.getGlobalTransactionIdUid().extractTimestamp(); if (log.isDebugEnabled()) { log.debug("recovered XID timestamp: " + txTimestamp + " - oldest in-flight TX timestamp: " + oldestTransactionTimestamp); } if (txTimestamp >= oldestTransactionTimestamp) { if (log.isDebugEnabled()) { log.debug("skipping XID of in-flight transaction: " + recoveredXid); } continue; } if (log.isDebugEnabled()) { log.debug("rolling back in-doubt branch with XID " + recoveredXid + " on " + uniqueName); } boolean success = rollback(uniqueName, recoveredXid); if (success) abortedCount++; } return abortedCount; }
Set<DanglingTransaction> danglingTransactions = getDanglingTransactionsInRecoveredXids(uniqueNames, tlog.getGtrid()); long txTimestamp = gtrid.extractTimestamp(); if (log.isDebugEnabled()) { log.debug("recovered XID timestamp: " + txTimestamp + " - oldest in-flight TX timestamp: " + oldestTransactionTimestamp); }
Set<DanglingTransaction> danglingTransactions = getDanglingTransactionsInRecoveredXids(uniqueNames, tlog.getGtrid()); long txTimestamp = gtrid.extractTimestamp(); if (log.isDebugEnabled()) log.debug("recovered XID timestamp: " + txTimestamp + " - oldest in-flight TX timestamp: " + oldestTransactionTimestamp);
Set<DanglingTransaction> danglingTransactions = getDanglingTransactionsInRecoveredXids(uniqueNames, tlog.getGtrid()); long txTimestamp = gtrid.extractTimestamp(); if (log.isDebugEnabled()) log.debug("recovered XID timestamp: " + txTimestamp + " - oldest in-flight TX timestamp: " + oldestTransactionTimestamp);
Set<DanglingTransaction> danglingTransactions = getDanglingTransactionsInRecoveredXids(uniqueNames, tlog.getGtrid()); long txTimestamp = gtrid.extractTimestamp(); if (log.isDebugEnabled()) { log.debug("recovered XID timestamp: " + txTimestamp + " - oldest in-flight TX timestamp: " + oldestTransactionTimestamp); }
@Override public int compare(BitronixTransaction t1, BitronixTransaction t2) { Long timestamp1 = t1.getResourceManager().getGtrid().extractTimestamp(); Long timestamp2 = t2.getResourceManager().getGtrid().extractTimestamp(); int compareTo = timestamp1.compareTo(timestamp2); if (compareTo == 0 && !t1.getResourceManager().getGtrid().equals(t2.getResourceManager().getGtrid())) { // if timestamps are equal, use the Uid as the tie-breaker. the !equals() check above avoids an expensive string compare() here. return t1.getGtrid().compareTo(t2.getGtrid()); } return compareTo; } };
@Override public int compare(BitronixTransaction t1, BitronixTransaction t2) { Long timestamp1 = t1.getResourceManager().getGtrid().extractTimestamp(); Long timestamp2 = t2.getResourceManager().getGtrid().extractTimestamp(); int compareTo = timestamp1.compareTo(timestamp2); if (compareTo == 0 && !t1.getResourceManager().getGtrid().equals(t2.getResourceManager().getGtrid())) { // if timestamps are equal, use the Uid as the tie-breaker. the !equals() check above avoids an expensive string compare() here. return t1.getGtrid().compareTo(t2.getGtrid()); } return compareTo; } };
currentTx.setActive(threadContext.getTimeout()); inFlightTransactions.put(currentTx, clearContextSynchronization); if (log.isDebugEnabled()) { log.debug("begun new transaction at " + new Date(currentTx.getResourceManager().getGtrid().extractTimestamp())); } } catch (RuntimeException ex) { clearContextSynchronization.afterCompletion(Status.STATUS_NO_TRANSACTION);
currentTx.setActive(threadContext.getTimeout()); inFlightTransactions.put(currentTx, clearContextSynchronization); if (log.isDebugEnabled()) { log.debug("begun new transaction at " + new Date(currentTx.getResourceManager().getGtrid().extractTimestamp())); } } catch (RuntimeException ex) { clearContextSynchronization.afterCompletion(Status.STATUS_NO_TRANSACTION);
/** * Start a new transaction and bind the context to the calling thread. * @throws NotSupportedException if a transaction is already bound to the calling thread. * @throws SystemException if the transaction manager is shutting down. */ public void begin() throws NotSupportedException, SystemException { if (log.isDebugEnabled()) log.debug("beginning a new transaction"); if (isShuttingDown()) throw new BitronixSystemException("cannot start a new transaction, transaction manager is shutting down"); dumpTransactionContexts(); BitronixTransaction currentTx = getCurrentTransaction(); if (currentTx != null) throw new NotSupportedException("nested transactions not supported"); currentTx = createTransaction(); ClearContextSynchronization clearContextSynchronization = new ClearContextSynchronization(currentTx); try { currentTx.getSynchronizationScheduler().add(clearContextSynchronization, Scheduler.ALWAYS_LAST_POSITION -1); currentTx.setActive(getOrCreateCurrentContext().getTimeout()); if (log.isDebugEnabled()) log.debug("begun new transaction at " + new Date(currentTx.getResourceManager().getGtrid().extractTimestamp())); } catch (RuntimeException ex) { clearContextSynchronization.afterCompletion(Status.STATUS_NO_TRANSACTION); throw ex; } catch (SystemException ex) { clearContextSynchronization.afterCompletion(Status.STATUS_NO_TRANSACTION); throw ex; } }
/** * Start a new transaction and bind the context to the calling thread. * @throws NotSupportedException if a transaction is already bound to the calling thread. * @throws SystemException if the transaction manager is shutting down. */ public void begin() throws NotSupportedException, SystemException { if (log.isDebugEnabled()) log.debug("beginning a new transaction"); if (isShuttingDown()) throw new BitronixSystemException("cannot start a new transaction, transaction manager is shutting down"); dumpTransactionContexts(); BitronixTransaction currentTx = getCurrentTransaction(); if (currentTx != null) throw new NotSupportedException("nested transactions not supported"); currentTx = createTransaction(); ClearContextSynchronization clearContextSynchronization = new ClearContextSynchronization(currentTx); try { currentTx.getSynchronizationScheduler().add(clearContextSynchronization, Scheduler.ALWAYS_LAST_POSITION -1); currentTx.setActive(getOrCreateCurrentContext().getTimeout()); if (log.isDebugEnabled()) log.debug("begun new transaction at " + new Date(currentTx.getResourceManager().getGtrid().extractTimestamp())); } catch (RuntimeException ex) { clearContextSynchronization.afterCompletion(Status.STATUS_NO_TRANSACTION); throw ex; } catch (SystemException ex) { clearContextSynchronization.afterCompletion(Status.STATUS_NO_TRANSACTION); throw ex; } }
public void testExtracts() throws Exception { byte[] timestamp = Encoder.longToBytes(System.currentTimeMillis()); byte[] sequence = Encoder.intToBytes(1); byte[] serverId = "my-server-id".getBytes(); int uidLength = serverId.length + timestamp.length + sequence.length; byte[] uidArray = new byte[uidLength]; System.arraycopy(serverId, 0, uidArray, 0, serverId.length); System.arraycopy(timestamp, 0, uidArray, serverId.length, timestamp.length); System.arraycopy(sequence, 0, uidArray, serverId.length + timestamp.length, sequence.length); Uid uid = new Uid(uidArray); assertTrue(Arrays.equals(serverId, uid.extractServerId())); assertEquals(Encoder.bytesToLong(timestamp, 0), uid.extractTimestamp()); assertEquals(Encoder.bytesToInt(sequence, 0), uid.extractSequence()); }
public void testExtracts() throws Exception { byte[] timestamp = Encoder.longToBytes(System.currentTimeMillis()); byte[] sequence = Encoder.intToBytes(1); byte[] serverId = "my-server-id".getBytes(); int uidLength = serverId.length + timestamp.length + sequence.length; byte[] uidArray = new byte[uidLength]; System.arraycopy(serverId, 0, uidArray, 0, serverId.length); System.arraycopy(timestamp, 0, uidArray, serverId.length, timestamp.length); System.arraycopy(sequence, 0, uidArray, serverId.length + timestamp.length, sequence.length); Uid uid = new Uid(uidArray); assertTrue(Arrays.equals(serverId, uid.extractServerId())); assertEquals(Encoder.bytesToLong(timestamp, 0), uid.extractTimestamp()); assertEquals(Encoder.bytesToInt(sequence, 0), uid.extractSequence()); }