activemq-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ryan Stewart <>
Subject Re: Only memory transaction store with JDBC persistence adapter??
Date Tue, 29 Jul 2008 13:09:44 GMT

rajdavies wrote:
> On 29 Jul 2008, at 05:41, bwtaylor wrote:
>> I'm kind of baffled by this, as I thought you had to flush the  
>> prepare out to
>> a durable media, too. This is in fact, what
>> claims  
>> happens. I
>> don't see how XA transactions with the JDBCMessageStore is achieving  
>> the
>> proper level of durability during the prepare stage. Hopfully one of  
>> the
>> ActiveMQ developers can clear this up.
>> It looks like JDBCPersistenceAdapter's  
>> createQueueMessageStore(destination)
>> method instantiates a new JDBCMessageStore called rc and then returns
>> transactionStore.proxy(rc). The proxy method produces a MessageStore
>> implementation by constructing an inner class based on a new
>> ProxyMessageStore(messageStore), overriding addMessage and  
>> removeMessage to
>> proxy through the original MemoryTransactionStore to the delegate
>> messageStore, which is the JDBCMessageStore. The proxying happens by  
>> adding
>> an AddMessageCommand or a RemoveMessageCommand inner class  
>> implementation to
>> the Tx object (which is itself a static inner class of
>> MessageTransactionStore).
>> This Tx objects can be stored in either of two ConcurrentHashMaps  
>> called
>> inflightTransactions and preparedTransactions. Calling prepare() on
>> MemoryTransactionStore just shuffles the Tx from the former to the  
>> later and
>> does not do anything else. In particular, it appears that the  
>> underlying
>> JDBCMessageStore is not involved in the prepare step.
>> During the commit, the XATransaction calls commit, which passes  
>> through to
>> the transactionStore. In our case, MemoryTransactionStore gets and  
>> removes
>> the Tx object from preparedTransactions (assuming two phase commit  
>> is on),
>> and tx.commit() is called. The tx object executes the commands it  
>> added
>> above, first iterating over all adds and then all removes. When these
>> included JDBCMessageStore's addMessage or removeMessage, a  
>> JDBCAdapter is
>> used to issue SQL to the database. The underlying jdbc connection  
>> commits
>> when told to do so from the TransactionContext object, which commits  
>> when
>> JDBCPersistenceAdapter's commitTransaction method is called. I don't  
>> quite
>> see how this is connected to the XATransaction's calling of commit().
> The journaled JDBC store uses a transaction log - can you not use that ?

For one thing, we are setting up a master/slave configuration using JDBC, so
no journaling.

A more compelling reason is that the
JournalPersistenceAdapter/JournalTransactionStore suffers from the same
thing. All of the TransactionStores do. Yes, some write out transaction
"events" to some sort of persistent store, but they all use some Map
implementation to store the prepared transactions. For example, from
JournalTransactionStore (my comments in [])--

    public void prepare(TransactionId txid) throws IOException {
[It gets the transaction in question based on the transaction id]
        Tx tx = null;
        synchronized (inflightTransactions) {
            tx = inflightTransactions.remove(txid);
        if (tx == null) {
[It writes a transaction event using the persistence adapter]
JournalTransaction(JournalTransaction.XA_PREPARE, txid, false), true);
[Then it puts the transaction in question into a Map to mark it as prepared]
        synchronized (preparedTransactions) {
            preparedTransactions.put(txid, tx);

In this class, preparedTransactions is a LinkedHashMap. Perhaps someone has
made the mistaken assumption that the TransactionId object contains all the
necessary data for recovering a transaction? All of the TransactionStore
implementations have similar code for the prepare method, though the
MemoryTransactionStore used by the JDBCPersistenceAdapter doesn't even write
a transaction event to the database.
View this message in context:
Sent from the ActiveMQ - User mailing list archive at

View raw message