activemq-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Hiram Chirino" <hi...@hiramchirino.com>
Subject Re: Only memory transaction store with JDBC persistence adapter??
Date Thu, 14 Aug 2008 17:30:36 GMT
Hi in the case of the Journal implementation, that map of in flight
transactions gets repopulated with the transactions when the journal
first gets started.  The journal re-plays all the journal records and
this re-builds the map of non-committed transactions.  See the
recover() method.

BTW.. on a related note I just fixed issue
https://issues.apache.org/activemq/browse/AMQ-1886, this makes the JMS
transactions commit as a single UOW to the JDBC store when a Journal
is not used.  But still does not address your XA problem.

Regards,
Hiram

On Tue, Jul 29, 2008 at 9:09 AM, Ryan Stewart <rds6235@gmail.com> wrote:
>
>
> 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
>>> http://activemq.apache.org/how-do-transactions-work.html 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) {
>            return;
>        }
> [It writes a transaction event using the persistence adapter]
>        peristenceAdapter.writeCommand(new
> 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: http://www.nabble.com/Only-memory-transaction-store-with-JDBC-persistence-adapter---tp18657395p18711766.html
> Sent from the ActiveMQ - User mailing list archive at Nabble.com.
>
>



-- 
Regards,
Hiram

Blog: http://hiramchirino.com

Open Source SOA
http://open.iona.com

Mime
View raw message