Buggy code:
public class TransactionalSpoutCoordinator implements IRichSpout { public static final BigInteger INIT_TXID = new BigInteger ( "1" ) ; public static final String TRANSACTION_BATCH_STREAM_ID = ( TransactionalSpoutCoordinator . class . getName ( ) ) + "//batch" ; public static final String TRANSACTION_COMMIT_STREAM_ID = ( TransactionalSpoutCoordinator . class . getName ( ) ) + "//commit" ; private static final String CURRENT_TX = "currtx" ; private static final String META_DIR = "meta" ; private ITransactionalSpout _spout ; private Coordinator _coordinator ; private TransactionalState _state ; private RotatingTransactionalState _coordinatorState ; Map < BigInteger , TransactionalSpoutCoordinator . TransactionStatus > _activeTx = new HashMap < BigInteger , TransactionalSpoutCoordinator . TransactionStatus > ( ) ; private SpoutOutputCollector _collector ; BigInteger _currTransaction ; int _maxTransactionActive ; TransactionalSpoutCoordinator . StateInitializer _initializer ; public TransactionalSpoutCoordinator ( ITransactionalSpout spout ) { } @ Override public void open ( Map conf , TopologyContext context , SpoutOutputCollector collector ) { } @ Override public void close ( ) { } @ Override public void nextTuple ( ) { } @ Override public void ack ( Object msgId ) { TransactionAttempt tx = ( ( TransactionAttempt ) ( msgId ) ) ; TransactionalSpoutCoordinator . TransactionStatus status = _activeTx . get ( tx . getTransactionId ( ) ) ; if ( ! ( tx . equals ( status . attempt ) ) ) { throw new IllegalStateException ( ( ( ( "Coordinator<seq2seq4repair_space>got<seq2seq4repair_space>into<seq2seq4repair_space>a<seq2seq4repair_space>bad<seq2seq4repair_space>state:<seq2seq4repair_space>acked<seq2seq4repair_space>transaction<seq2seq4repair_space>" + ( tx . toString ( ) ) ) + "<seq2seq4repair_space>does<seq2seq4repair_space>not<seq2seq4repair_space>match<seq2seq4repair_space>up<seq2seq4repair_space>with<seq2seq4repair_space>stored<seq2seq4repair_space>attempt:<seq2seq4repair_space>" ) + status ) ) ; } if ( ( status . status ) == ( TransactionalSpoutCoordinator . AttemptStatus . PROCESSING ) ) { status . status = TransactionalSpoutCoordinator . AttemptStatus . PROCESSED ; } else if ( ( status . status ) == ( TransactionalSpoutCoordinator . AttemptStatus . COMMITTING ) ) { _activeTx . remove ( tx . getTransactionId ( ) ) ; <START_BUG> _coordinatorState . commit ( tx . getTransactionId ( ) ) ; <END_BUG> _currTransaction = nextTransactionId ( tx . getTransactionId ( ) ) ; _state . setData ( TransactionalSpoutCoordinator . CURRENT_TX , _currTransaction ) ; } sync ( ) ; } @ Override public void fail ( Object msgId ) { } @ Override public void declareOutputFields ( OutputFieldsDeclarer declarer ) { } private void sync ( ) { } @ Override public Map < String , Object > getComponentConfiguration ( ) { } private static enum AttemptStatus { PROCESSING , PROCESSED , COMMITTING ; } private static class TransactionStatus { TransactionAttempt attempt ; TransactionalSpoutCoordinator . AttemptStatus status ; public TransactionStatus ( TransactionAttempt attempt ) { } @ Override public String toString ( ) { } } private static final BigInteger ONE = new BigInteger ( "1" ) ; private BigInteger nextTransactionId ( BigInteger id ) { } private BigInteger getStoredCurrTransaction ( TransactionalState state ) { } private class StateInitializer implements RotatingTransactionalState . StateInitializer { @ Override public Object init ( BigInteger txid , Object lastState ) { } } }

Fix:
_coordinatorState . cleanupBefore ( tx . getTransactionId ( ) ) ;