activemq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Stan Lewis (JIRA)" <j...@apache.org>
Subject [jira] Updated: (AMQ-2880) Exception thrown during commit leads to message loss
Date Tue, 07 Sep 2010 20:48:40 GMT

     [ https://issues.apache.org/activemq/browse/AMQ-2880?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Stan Lewis updated AMQ-2880:
----------------------------

    Attachment: xa-test-case.txt
                patch_for_xa_transaction.txt

Here's a test for XATransaction.  I'm finding however that catching the exception within commit
and calling rollback() from there doesn't seem to fix the issue.  Instead it seems like the
message is effectively lost, as when the dummy persistent store throws it's exception the
message is out of the database, I wouldn't have expected that.  Also to properly rollback
in the client I had to call XAResource.start() for some reason, also a bit unexpected.  Anyway,
am also attaching the changes I had done to XATransaction.java.

> Exception thrown during commit leads to message loss
> ----------------------------------------------------
>
>                 Key: AMQ-2880
>                 URL: https://issues.apache.org/activemq/browse/AMQ-2880
>             Project: ActiveMQ
>          Issue Type: Bug
>          Components: Broker
>    Affects Versions: 5.4.0
>            Reporter: Stan Lewis
>            Assignee: Gary Tully
>             Fix For: 5.4.1
>
>         Attachments: patch_for_xa_transaction.txt, test-case.txt, test-case.txt, xa-test-case.txt
>
>
> In cases where JDBC persistence is used and the database server is under a fair bit of
load it's sometimes possible for table/row locks to time out, which means you'll see exceptions
such as:
> java.sql.BatchUpdateException: Lock wait timeout exceeded; try restarting transaction
> at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1693)
> at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1108)
> at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
> at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
> at org.apache.activemq.store.jdbc.TransactionContext.executeBatch(TransactionContext.java:98)
> at org.apache.activemq.store.jdbc.TransactionContext.executeBatch(TransactionContext.java:80)
> at org.apache.activemq.store.jdbc.TransactionContext.commit(TransactionContext.java:161)
> at org.apache.activemq.store.jdbc.JDBCPersistenceAdapter.commitTransaction(JDBCPersistenceAdapter.java:504)
> at org.apache.activemq.store.memory.MemoryTransactionStore$Tx.commit(MemoryTransactionStore.java:109)
> at org.apache.activemq.store.memory.MemoryTransactionStore.commit(MemoryTransactionStore.java:220)
> at org.apache.activemq.transaction.XATransaction.commit(XATransaction.java:73)
> at org.apache.activemq.broker.TransactionBroker.commitTransaction(TransactionBroker.java:176)
> at org.apache.activemq.broker.MutableBrokerFilter.commitTransaction(MutableBrokerFilter.java:103)
> at org.apache.activemq.broker.TransportConnection.processCommitTransactionTwoPhase(TransportConnection.java:430)
> at org.apache.activemq.command.TransactionInfo.visit(TransactionInfo.java:102)
> at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:309)
> at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:185)
> at org.apache.activemq.transport.TransportFilter.onCommand(TransportFilter.java:69)
> at org.apache.activemq.transport.WireFormatNegotiator.onCommand(WireFormatNegotiator.java:113)
> at org.apache.activemq.transport.InactivityMonitor.onCommand(InactivityMonitor.java:217)
> at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)
> at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:219)
> at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:201)
> at java.lang.Thread.run(Thread.java:636)
> In this case the connection to the database is fine and what we should do is retry the
transaction as it's a temporary failure condition.  Instead what happens is the broker moves
to the next message in the queue, leaving the current message in the database.  The message
won't show up in the web console and cannot be consumed by any consumers until the broker
is restarted.
> Attached is a test case that simulates the error condition in a controlled fashion by
using a subclassed JDBCPersistenceAdapter that will throw an exception in commitTransaction
as necessary.  So the producer sends 10 messages and then the consumer tries to consume them,
during this time the persistence adapter will throw an exception during commitTransaction.
 Then the condition is cleared and the consumer can consume all 10 messages, however the consumer
only consumes 9 messages, the 1st message in the sequence is still in the database.  Hopefully
the logging makes this clear.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message