Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
None
-
None
-
None
Description
As an example, in TransactionStateManager.timedOutTransactions(), we read the state and pendingState without acquiring the lock for each metadata object:
inReadLock(stateLock) { transactionMetadataCache.flatMap { case (_, entry) => entry.metadataPerTransactionalId.filter { case (_, txnMetadata) => if (txnMetadata.pendingTransitionInProgress) { false } else { txnMetadata.state match { case Ongoing => txnMetadata.txnStartTimestamp + txnMetadata.txnTimeoutMs < now case _ => false } } }.map { case (txnId, txnMetadata) => TransactionalIdAndProducerIdEpoch(txnId, txnMetadata.producerId, txnMetadata.producerEpoch) } } }
The start timestamp is volatile, so it can be safely read, but we also read the pendingState and state, which are not.