You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@activemq.apache.org by "Stan Lewis (JIRA)" <ji...@apache.org> on 2010/08/26 14:38:40 UTC

[jira] Created: (AMQ-2880) Exception thrown during commit leads to message loss

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
         Attachments: 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.


[jira] Issue Comment Edited: (AMQ-2880) Exception thrown during commit leads to message loss

Posted by "Gary Tully (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/activemq/browse/AMQ-2880?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=61734#action_61734 ] 

Gary Tully edited comment on AMQ-2880 at 9/8/10 12:37 PM:
----------------------------------------------------------

r995119 
new xa test variant from patch applied. thanks for the work on this one. XA case is now sorted.



      was (Author: gtully):
    r995119 
new xa test variant from patch applied. thanks for the work on this one. XA case is not sorted.


  
> 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.


[jira] Updated: (AMQ-2880) Exception thrown during commit leads to message loss

Posted by "Stan Lewis (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2880?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

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

    Attachment: test-case.txt

This shows the problem better, as each time a new consumer is created to receive a message from the queue a message is lost.

> 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
>         Attachments: test-case.txt, 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.


[jira] Updated: (AMQ-2880) Exception thrown during commit leads to message loss

Posted by "Stan Lewis (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2880?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

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

    Attachment: test-case.txt

> 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
>         Attachments: 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.


[jira] Updated: (AMQ-2880) Exception thrown during commit leads to message loss

Posted by "Stan Lewis (JIRA)" <ji...@apache.org>.
     [ 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.


[jira] Commented: (AMQ-2880) Exception thrown during commit leads to message loss

Posted by "Stan Lewis (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/activemq/browse/AMQ-2880?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=61454#action_61454 ] 

Stan Lewis commented on AMQ-2880:
---------------------------------

Just a note to simulate the real lock timeout exception using MySQL you can just lock some rows in the table, for example:

start transaction;
select id from activemq_msgs limit 10 for update;

then try and consume some messages.  ActiveMQ will get block and then get a lock timeout when it hits these locked rows.  Then release the lock with:

commit;

after consuming all of the messages in the queue that you can you'll see those locked rows are still in the table and hadn't been consumed.

> 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
>         Attachments: 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.


[jira] Assigned: (AMQ-2880) Exception thrown during commit leads to message loss

Posted by "Gary Tully (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2880?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Gary Tully reassigned AMQ-2880:
-------------------------------

    Assignee: Gary Tully

> 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
>         Attachments: test-case.txt, 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.


[jira] Updated: (AMQ-2880) Exception thrown during commit leads to message loss

Posted by "Stan Lewis (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2880?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

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

    Attachment: patch_for_xa_transaction.txt

This should take care of XA transactions.

> 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
>
>
> 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.


[jira] Reopened: (AMQ-2880) Exception thrown during commit leads to message loss

Posted by "Stan Lewis (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2880?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Stan Lewis reopened AMQ-2880:
-----------------------------


This problem also occurs with XA transactions (like in the example stack trace) so we need a similar fix for this scenario.

> 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: test-case.txt, 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.


[jira] Resolved: (AMQ-2880) Exception thrown during commit leads to message loss

Posted by "Gary Tully (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2880?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Gary Tully resolved AMQ-2880.
-----------------------------

    Fix Version/s: 5.4.1
       Resolution: Fixed

resolved in r991218

a jms transaction rollback was needed in the even of a store failure on an ack. in addition test case needed maxredeliveries > numMessages to ensure replayed messages were not sent to dlq.
fix an test from patch applied with thanks.

> 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: test-case.txt, 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.


[jira] Resolved: (AMQ-2880) Exception thrown during commit leads to message loss

Posted by "Gary Tully (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2880?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Gary Tully resolved AMQ-2880.
-----------------------------

    Resolution: Fixed

r995119 
new xa test variant from patch applied. thanks for the work on this one. XA case is not sorted.



> 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.


[jira] Updated: (AMQ-2880) Exception thrown during commit leads to message loss

Posted by "Stan Lewis (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2880?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

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

    Attachment:     (was: patch_for_xa_transaction.txt)

> 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: test-case.txt, 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.