Support safe-updates mode in MySQLMaxValueIncrementer

Prior to this commit, MySQLMaxValueIncrementer could not be used when
the MySQL database was configured to use safe-updates mode.

See https://dev.mysql.com/doc/refman/8.0/en/mysql-tips.html#safe-updates

This commit introduces a `limit 1` clause to the generated update
statement to allow MySQLMaxValueIncrementer to be compatible with
MySQL safe-updates mode.

Closes gh-26858
This commit is contained in:
Sam Brannen
2021-04-29 15:37:40 +02:00
parent 607d918340
commit 697108cc42
2 changed files with 23 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,22 +40,27 @@ import org.springframework.jdbc.support.JdbcUtils;
*
* <p>Example:
*
* <pre class="code">create table tab (id int unsigned not null primary key, text varchar(100));
* <pre class="code">
* create table tab (id int unsigned not null primary key, text varchar(100));
* create table tab_sequence (value int not null);
* insert into tab_sequence values(0);</pre>
*
* If "cacheSize" is set, the intermediate values are served without querying the
* <p>If {@code cacheSize} is set, the intermediate values are served without querying the
* database. If the server or your application is stopped or crashes or a transaction
* is rolled back, the unused values will never be served. The maximum hole size in
* numbering is consequently the value of cacheSize.
* numbering is consequently the value of {@code cacheSize}.
*
* <p>It is possible to avoid acquiring a new connection for the incrementer by setting the
* "useNewConnection" property to false. In this case you <i>MUST</i> use a non-transactional
* storage engine like MYISAM when defining the incrementer table.
*
* <p>As of Spring Framework 5.3.7, {@code MySQLMaxValueIncrementer} is compatible with
* <a href="https://dev.mysql.com/doc/refman/8.0/en/mysql-tips.html#safe-updates">MySQL safe updates mode</a>.
*
* @author Jean-Pierre Pawlak
* @author Thomas Risberg
* @author Juergen Hoeller
* @author Sam Brannen
*/
public class MySQLMaxValueIncrementer extends AbstractColumnMaxValueIncrementer {
@@ -141,7 +146,7 @@ public class MySQLMaxValueIncrementer extends AbstractColumnMaxValueIncrementer
String columnName = getColumnName();
try {
stmt.executeUpdate("update " + getIncrementerName() + " set " + columnName +
" = last_insert_id(" + columnName + " + " + getCacheSize() + ")");
" = last_insert_id(" + columnName + " + " + getCacheSize() + ") limit 1");
}
catch (SQLException ex) {
throw new DataAccessResourceFailureException("Could not increment " + columnName + " for " +