activemq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "James Strachan" <>
Subject Re: (AMQ 992) DefaultDatabaseLocker and mysql
Date Tue, 28 Nov 2006 14:47:49 GMT
On 11/21/06, slotito <> wrote:
> Hi,
> I am trying to get MySQL to work in the Master/Slave JDBC configuration -
> the default sql does not lock the table properly.
> I added a MysqlJDBCAdapter that extends
> so I could
> override the lockCreateStatement.
> I then edited the resources so that the mysql-ab_jdbc_driver would use the
> MysqlJDBCAdapter instead of the DefaultJDBCAdapter.
> The new locking statement is: LOCK TABLE ACTIVEMQ_LOCK WRITE  (which works
> in MySQL 5.x at least)
> Unfortunately, once I run it with the new code, it gets stuck in the
> following block (from
>         PreparedStatement statement =
> connection.prepareStatement(statements.getLockCreateStatement());
>         while (true) {
>             try {
>       "Attempting to acquire the exclusive lock to become
> the Master broker");
>                 boolean answer = statement.execute();
>                 if (answer) {
>                     break;
>                 }
>             }
>             catch (Exception e) {
>                 if (stopping) {
>                     throw new Exception("Cannot start broker as being asked
> to shut down. Interupted attempt to acquire lock: " + e, e);
>                 }
>                 log.error("Failed to acquire lock: " + e, e);
>             }
>             log.debug("Sleeping for " + sleepTime + " milli(s) before trying
> again to get the lock...");
>             Thread.sleep(sleepTime);
>         }
> Unlike the original SQL ("SELECT* FROM ACTIVEMQ_LOCK FOR UPDATE"), the lock
> table command for Mysql doesn't return a ResultSet.  This means that
> "answer" above will always be false, even though the table is successfully
> locked, and it basically goes into an infinite loop "Attempting to
> acquire...".
> (see
> I see three ways to get this working, but I might be missing something.
> I've never contributed anything to this project so I'd like to get some
> advice from you guys.
> 1) I'm pretty sure it is possible to allow multiple queries in a statement
> through the use of a connection string parameter (?allowMultiQueries=true)
> in the mysql driver - i.e. it would allow "LOCK TABLE ACTIVEMQ_LOCK WRITE;
> SELECT * FROM ACTIVEMQ_LOCK" which would return a ResultSet and set "answer"
> to true.  This would just be a documentation effort, basically making sure
> anyone using the Master/Slave JDBC configuration with MySQL knows to set
> that connection parameter.
> 2) I could create a MysqlDatabaseLocker and the necessary resource/config
> changes, then override that method and remove the "answer" part.  This seems
> like overkill since none of the other databases seem to require their own at
> this point.
> 3) I could remove the boolean answer from the DefaultDatabaseLocker.  Is it
> currently necessary?  If there's anything kind of database access error, it
> will just throw a SQLException anyway.  Other connections will wait for the
> lock to become available before they return from the statement.execute(),
> right?
> Any thoughts on this?

Thanks for this great contribution Steve!

Firstly - I've raised a JIRA to track this issue...

I agree with 3), I think we should ignore the check for a result set
on the SQL statement. I've made this change in trunk now which should
help. I've also committed your patch to trunk - providing a
MySqlJDBCAdapter which uses the SQL you so kindly submitted for the
exclusive lock. I tried it on my machine with MySQL Connector/J 5.0.4
and it seemed to work great.

I wonder could you see if it works for you? If so we can close the issue.



View raw message