Hello.
The logic of your application is clear and should work (though I haven't
been digging deeply inside the code). Check that the table type is
InnoDB. 4.0.1 version is rather old and could have lots of bugs, I
recommend you to upgrade to the latest release. Another reason, is that
your algorithm generates overlapped intervals of transerid values, but
this is not a MySQL issue. Enable the general log and check the
sequences of queries produced by your container.
Patrick Duda wrote:
> Hi,
>
> I am running MySQL 4.0.1 with j/connector 3.1 and I am having problems
> trying to figure out why I am not getting the results I am expecting.
>
> I have a table that is used for generating primary keys. It only has
> one item, an int that is incremented each time a key is needed. This is
> not my code or my design so using something like auto_incrament is not
> an option.
>
> The code runs under a container and our desire is to have several
> different containers running at the same time, all accessing the same
> database. Each container is independent so the controls need to be on
> the database side.
>
> The solution also needs to be portable to other databases so I am trying
> to stay with standard JDBC or SQL options.
>
> The code for generating a new key is this:
>
> try {
> c = DatabaseSetup.getDBConnection();
>
> c.setAutoCommit(false);
>
> statement =
> c.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
> ResultSet.CONCUR_UPDATABLE);
>
> rs = statement.executeQuery("select transfer_id from transferid for
> update");
>
> if (!rs.next()) {
> nextTransferId = nextTransferId + 1;
> StringBuffer query = new StringBuffer();
> query.append("insert into transferid(transfer_id) values
> (");
> query.append(nextTransferId);
> query.append(")");
> tempStatement = c.createStatement();
> // Now Update the old value with new value
> tempStatement.executeUpdate(query.toString());
> } else {
> rs.previous();
> while( rs != null && rs.next() ) {
> nextTransferId = rs.getInt(1);
> // Get the transfer Id and increment it instead of
> using
> // Db Specific sequence
> nextTransferId = nextTransferId + 1;
> // Now Update the old value with new value
> tempStatement = c.createStatement();
> tempStatement.executeUpdate("update transferid set "+
> "transfer_id= "+ nextTransferId);
> }
> }
> } catch (SQLException e) {
>
> if( c != null )
> {
> try
> {
> c.rollback();
> c.setAutoCommit(true);
> }
> catch( SQLException ex )
> {
> }
> }
> throw new DBException(i18n.getMessage("dbInsertErr"),
> e);
> } finally {
> try {
> c.commit();
> c.setAutoCommit(true);
> if (statement != null) {
> statement.close();
> }
> if (tempStatement != null) {
> tempStatement.close();
> }
> if (rs != null) {
> rs.close();
> }
> if (c != null) {
> DatabaseSetup.returnDBConnection(c);
> }
> } catch (SQLException sql) {
> logger.warn(i18n.getMessage("dbStatementErr"), sql);
> }
> }
> return nextTransferId;
> }
>
> I thought, that if I turned off autocommit I would enter a transaction.
> Then, by using the "select...for update", that I would take and hole a
> lock on the table. That no other transaction would be able to read the
> table until I released the lock. However, this is not what I am seeing
> when I run some tests. I start up a number of containers and then fire
> off a bunch of jobs to each. Each of these jobs will hit the above
> code. The problem is that every so often I see the following error
> message.
>
> Error inserting records into database [Caused by: Duplicate entry '131'
> for key 1]
>
> What am I doing wrong?
>
> How am I suppose to be doing this via JDBC? I know it should work...
>
> Thanks
>
--
For technical support contracts, goto https://order.mysql.com/?ref=ensita
This email is sponsored by Ensita.NET http://www.ensita.net/
__ ___ ___ ____ __
/ |/ /_ __/ __/ __ \/ / Gleb Paharenko
/ /|_/ / // /\ \/ /_/ / /__ [EMAIL PROTECTED]
/_/ /_/\_, /___/\___\_\___/ MySQL AB / Ensita.NET
<___/ www.mysql.com
--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe: http://lists.mysql.com/[EMAIL PROTECTED]