diff --git a/ebean-api/src/main/java/io/ebean/Query.java b/ebean-api/src/main/java/io/ebean/Query.java index 435c3d58f..8b1d0fa03 100644 --- a/ebean-api/src/main/java/io/ebean/Query.java +++ b/ebean-api/src/main/java/io/ebean/Query.java @@ -210,13 +210,13 @@ public interface Query { } /** - * For update mode. + * FOR UPDATE wait mode. */ - enum ForUpdate { + enum LockWait { /** * Standard For update clause. */ - BASE, + WAIT, /** * For update with No Wait option. @@ -1685,9 +1685,9 @@ public interface Query { boolean isForUpdate(); /** - * Return the "for update" mode to use. + * Return the "for update" wait mode to use. */ - ForUpdate getForUpdateMode(); + LockWait getForUpdateLockWait(); /** * Return the lock type (strength) to use with "for update". diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/DatabasePlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/DatabasePlatform.java index 1ab232107..b8270025e 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/DatabasePlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/DatabasePlatform.java @@ -679,7 +679,7 @@ public class DatabasePlatform { public String completeSql(String sql, Query query) { if (query.isForUpdate()) { - sql = withForUpdate(sql, query.getForUpdateMode(), query.getForUpdateLockType()); + sql = withForUpdate(sql, query.getForUpdateLockWait(), query.getForUpdateLockType()); } return sql; } @@ -687,12 +687,12 @@ public class DatabasePlatform { /** * For update hint on the FROM clause (SQL server only). */ - public String fromForUpdate(Query.ForUpdate forUpdateMode) { + public String fromForUpdate(Query.LockWait lockWait) { // return null except for sql server return null; } - protected String withForUpdate(String sql, Query.ForUpdate forUpdateMode, Query.LockType lockType) { + protected String withForUpdate(String sql, Query.LockWait lockWait, Query.LockType lockType) { // silently assume the database does not support the "for update" clause. logger.info("it seems your database does not support the 'for update' clause"); return sql; diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/h2/H2Platform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/h2/H2Platform.java index e7a612ba2..cdc923824 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/h2/H2Platform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/h2/H2Platform.java @@ -51,7 +51,7 @@ public class H2Platform extends DatabasePlatform { } @Override - protected String withForUpdate(String sql, Query.ForUpdate forUpdateMode, Query.LockType lockType) { + protected String withForUpdate(String sql, Query.LockWait lockWait, Query.LockType lockType) { // NOWAIT and SKIP LOCKED currently not supported with H2 return sql + " for update"; } diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/hana/HanaPlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/hana/HanaPlatform.java index a79f2c946..5fb91fcc8 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/hana/HanaPlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/hana/HanaPlatform.java @@ -1,7 +1,7 @@ package io.ebean.config.dbplatform.hana; import io.ebean.Query; -import io.ebean.Query.ForUpdate; +import io.ebean.Query.LockWait; import io.ebean.annotation.PersistBatch; import io.ebean.annotation.Platform; import io.ebean.config.PlatformConfig; @@ -69,16 +69,16 @@ public class HanaPlatform extends DatabasePlatform { } @Override - protected String withForUpdate(String sql, ForUpdate forUpdateMode, Query.LockType lockType) { - switch (forUpdateMode) { - case BASE: + protected String withForUpdate(String sql, LockWait lockWait, Query.LockType lockType) { + switch (lockWait) { + case WAIT: return sql + " for update"; case NOWAIT: return sql + " for update nowait"; case SKIPLOCKED: return sql + " for update ignore locked"; default: - throw new IllegalArgumentException("Unknown update mode: " + forUpdateMode.name()); + throw new IllegalArgumentException("Unknown update mode: " + lockWait); } } diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/mysql/BaseMySqlPlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/mysql/BaseMySqlPlatform.java index 93b097ecd..b5d009a44 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/mysql/BaseMySqlPlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/mysql/BaseMySqlPlatform.java @@ -60,7 +60,7 @@ public abstract class BaseMySqlPlatform extends DatabasePlatform { } @Override - protected String withForUpdate(String sql, Query.ForUpdate forUpdateMode, Query.LockType lockType) { + protected String withForUpdate(String sql, Query.LockWait lockWait, Query.LockType lockType) { // NOWAIT and SKIP LOCKED currently not supported with MySQL return sql + " for update"; } diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/nuodb/NuoDbPlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/nuodb/NuoDbPlatform.java index 258a2ba6c..349793153 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/nuodb/NuoDbPlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/nuodb/NuoDbPlatform.java @@ -48,8 +48,8 @@ public class NuoDbPlatform extends DatabasePlatform { } @Override - protected String withForUpdate(String sql, Query.ForUpdate forUpdateMode, Query.LockType lockType) { - switch (forUpdateMode) { + protected String withForUpdate(String sql, Query.LockWait lockWait, Query.LockType lockType) { + switch (lockWait) { case NOWAIT: return sql + " for update nowait"; case SKIPLOCKED: diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/oracle/OraclePlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/oracle/OraclePlatform.java index e9c4419eb..c12ca8c74 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/oracle/OraclePlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/oracle/OraclePlatform.java @@ -79,8 +79,8 @@ public class OraclePlatform extends DatabasePlatform { } @Override - protected String withForUpdate(String sql, Query.ForUpdate forUpdateMode, Query.LockType lockType) { - switch (forUpdateMode) { + protected String withForUpdate(String sql, Query.LockWait lockWait, Query.LockType lockType) { + switch (lockWait) { case SKIPLOCKED: return sql + " for update skip locked"; case NOWAIT: diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/postgres/PostgresPlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/postgres/PostgresPlatform.java index 9a5ba9d3d..c4305f901 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/postgres/PostgresPlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/postgres/PostgresPlatform.java @@ -128,8 +128,8 @@ public class PostgresPlatform extends DatabasePlatform { } @Override - protected String withForUpdate(String sql, Query.ForUpdate forUpdateMode, Query.LockType lockType) { - switch (forUpdateMode) { + protected String withForUpdate(String sql, Query.LockWait lockWait, Query.LockType lockType) { + switch (lockWait) { case SKIPLOCKED: return sql + lock(lockType) + SKIP_LOCKED; case NOWAIT: diff --git a/ebean-api/src/main/java/io/ebean/config/dbplatform/sqlserver/SqlServerBasePlatform.java b/ebean-api/src/main/java/io/ebean/config/dbplatform/sqlserver/SqlServerBasePlatform.java index 119019db0..8a9c5b4be 100644 --- a/ebean-api/src/main/java/io/ebean/config/dbplatform/sqlserver/SqlServerBasePlatform.java +++ b/ebean-api/src/main/java/io/ebean/config/dbplatform/sqlserver/SqlServerBasePlatform.java @@ -105,8 +105,8 @@ abstract class SqlServerBasePlatform extends DatabasePlatform { * For update is part of the FROM clause on the base table for sql server. */ @Override - public String fromForUpdate(Query.ForUpdate forUpdateMode) { - switch (forUpdateMode) { + public String fromForUpdate(Query.LockWait lockWait) { + switch (lockWait) { case SKIPLOCKED: return "with (updlock,readpast)"; case NOWAIT: @@ -117,7 +117,7 @@ abstract class SqlServerBasePlatform extends DatabasePlatform { } @Override - protected String withForUpdate(String sql, Query.ForUpdate forUpdateMode, Query.LockType lockType) { + protected String withForUpdate(String sql, Query.LockWait lockWait, Query.LockType lockType) { // for update are hints on from clause of base table return sql; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java index 2229f3644..f3b133bc2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java @@ -237,7 +237,7 @@ public interface SpiQuery extends Query, TxnProfileEventCodes { * Return the ForUpdate mode. */ @Override - ForUpdate getForUpdateMode(); + LockWait getForUpdateLockWait(); /** * Return the bean descriptor for this query. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java index f23b15535..765251134 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java @@ -783,7 +783,7 @@ class CQueryBuilder { * Return the 'for update' FROM hint (sql server). */ String fromForUpdate(SpiQuery query) { - Query.ForUpdate mode = query.getForUpdateMode(); + Query.LockWait mode = query.getForUpdateLockWait(); if (mode == null) { return null; } else { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultFetchGroupQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultFetchGroupQuery.java index 144002e52..f0fc5a923 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultFetchGroupQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultFetchGroupQuery.java @@ -580,7 +580,7 @@ class DefaultFetchGroupQuery implements SpiFetchGroupQuery { } @Override - public ForUpdate getForUpdateMode() { + public LockWait getForUpdateLockWait() { throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup"); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index 9744a7245..8c790a121 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -236,7 +236,7 @@ public class DefaultOrmQuery implements SpiQuery { */ private Boolean autoTune; - private ForUpdate forUpdate; + private LockWait forUpdate; private LockType lockType; private boolean singleAttribute; @@ -965,35 +965,35 @@ public class DefaultOrmQuery implements SpiQuery { @Override public DefaultOrmQuery forUpdate() { - return setForUpdateWithMode(ForUpdate.BASE, LockType.Default); + return setForUpdateWithMode(LockWait.WAIT, LockType.Default); } @Override public Query forUpdate(LockType lockType) { - return setForUpdateWithMode(ForUpdate.BASE, lockType); + return setForUpdateWithMode(LockWait.WAIT, lockType); } @Override public Query forUpdateNoWait(LockType lockType) { - return setForUpdateWithMode(ForUpdate.NOWAIT, lockType); + return setForUpdateWithMode(LockWait.NOWAIT, lockType); } @Override public Query forUpdateSkipLocked(LockType lockType) { - return setForUpdateWithMode(ForUpdate.SKIPLOCKED, lockType); + return setForUpdateWithMode(LockWait.SKIPLOCKED, lockType); } @Override public DefaultOrmQuery forUpdateNoWait() { - return setForUpdateWithMode(ForUpdate.NOWAIT, LockType.Default); + return setForUpdateWithMode(LockWait.NOWAIT, LockType.Default); } @Override public DefaultOrmQuery forUpdateSkipLocked() { - return setForUpdateWithMode(ForUpdate.SKIPLOCKED, LockType.Default); + return setForUpdateWithMode(LockWait.SKIPLOCKED, LockType.Default); } - private DefaultOrmQuery setForUpdateWithMode(ForUpdate mode, LockType lockType) { + private DefaultOrmQuery setForUpdateWithMode(LockWait mode, LockType lockType) { this.forUpdate = mode; this.lockType = lockType; this.useBeanCache = CacheMode.OFF; @@ -1006,7 +1006,7 @@ public class DefaultOrmQuery implements SpiQuery { } @Override - public ForUpdate getForUpdateMode() { + public LockWait getForUpdateLockWait() { return forUpdate; } @@ -1146,6 +1146,9 @@ public class DefaultOrmQuery implements SpiQuery { } if (forUpdate != null) { sb.append(",forUpd:").append(forUpdate.ordinal()); + if (lockType != null) { + sb.append(",lt:").append(lockType.ordinal()); + } } if (id != null) { sb.append(",id:"); diff --git a/ebean-core/src/test/java/io/ebean/config/dbplatform/PostgresPlatformTest.java b/ebean-core/src/test/java/io/ebean/config/dbplatform/PostgresPlatformTest.java index 6a26330db..e15b4550b 100644 --- a/ebean-core/src/test/java/io/ebean/config/dbplatform/PostgresPlatformTest.java +++ b/ebean-core/src/test/java/io/ebean/config/dbplatform/PostgresPlatformTest.java @@ -30,24 +30,24 @@ public class PostgresPlatformTest { platform.configure(config); assertThat(config.isForUpdateNoKey()).isFalse(); - assertThat(platform.withForUpdate("X", Query.ForUpdate.SKIPLOCKED, Query.LockType.Default)).isEqualTo("X for update skip locked"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.NOWAIT, Query.LockType.Default)).isEqualTo("X for update nowait"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.BASE, Query.LockType.Default)).isEqualTo("X for update"); + assertThat(platform.withForUpdate("X", Query.LockWait.SKIPLOCKED, Query.LockType.Default)).isEqualTo("X for update skip locked"); + assertThat(platform.withForUpdate("X", Query.LockWait.NOWAIT, Query.LockType.Default)).isEqualTo("X for update nowait"); + assertThat(platform.withForUpdate("X", Query.LockWait.WAIT, Query.LockType.Default)).isEqualTo("X for update"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.SKIPLOCKED, Query.LockType.Update)).isEqualTo("X for update skip locked"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.SKIPLOCKED, Query.LockType.NoKeyUpdate)).isEqualTo("X for no key update skip locked"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.SKIPLOCKED, Query.LockType.Share)).isEqualTo("X for share skip locked"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.SKIPLOCKED, Query.LockType.KeyShare)).isEqualTo("X for key share skip locked"); + assertThat(platform.withForUpdate("X", Query.LockWait.SKIPLOCKED, Query.LockType.Update)).isEqualTo("X for update skip locked"); + assertThat(platform.withForUpdate("X", Query.LockWait.SKIPLOCKED, Query.LockType.NoKeyUpdate)).isEqualTo("X for no key update skip locked"); + assertThat(platform.withForUpdate("X", Query.LockWait.SKIPLOCKED, Query.LockType.Share)).isEqualTo("X for share skip locked"); + assertThat(platform.withForUpdate("X", Query.LockWait.SKIPLOCKED, Query.LockType.KeyShare)).isEqualTo("X for key share skip locked"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.NOWAIT, Query.LockType.Update)).isEqualTo("X for update nowait"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.NOWAIT, Query.LockType.NoKeyUpdate)).isEqualTo("X for no key update nowait"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.NOWAIT, Query.LockType.Share)).isEqualTo("X for share nowait"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.NOWAIT, Query.LockType.KeyShare)).isEqualTo("X for key share nowait"); + assertThat(platform.withForUpdate("X", Query.LockWait.NOWAIT, Query.LockType.Update)).isEqualTo("X for update nowait"); + assertThat(platform.withForUpdate("X", Query.LockWait.NOWAIT, Query.LockType.NoKeyUpdate)).isEqualTo("X for no key update nowait"); + assertThat(platform.withForUpdate("X", Query.LockWait.NOWAIT, Query.LockType.Share)).isEqualTo("X for share nowait"); + assertThat(platform.withForUpdate("X", Query.LockWait.NOWAIT, Query.LockType.KeyShare)).isEqualTo("X for key share nowait"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.BASE, Query.LockType.Update)).isEqualTo("X for update"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.BASE, Query.LockType.NoKeyUpdate)).isEqualTo("X for no key update"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.BASE, Query.LockType.Share)).isEqualTo("X for share"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.BASE, Query.LockType.KeyShare)).isEqualTo("X for key share"); + assertThat(platform.withForUpdate("X", Query.LockWait.WAIT, Query.LockType.Update)).isEqualTo("X for update"); + assertThat(platform.withForUpdate("X", Query.LockWait.WAIT, Query.LockType.NoKeyUpdate)).isEqualTo("X for no key update"); + assertThat(platform.withForUpdate("X", Query.LockWait.WAIT, Query.LockType.Share)).isEqualTo("X for share"); + assertThat(platform.withForUpdate("X", Query.LockWait.WAIT, Query.LockType.KeyShare)).isEqualTo("X for key share"); } @Test @@ -60,9 +60,9 @@ public class PostgresPlatformTest { platform.configure(config); assertThat(config.isForUpdateNoKey()).isTrue(); - assertThat(platform.withForUpdate("X", Query.ForUpdate.SKIPLOCKED, Query.LockType.Default)).isEqualTo("X for no key update skip locked"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.NOWAIT, Query.LockType.Default)).isEqualTo("X for no key update nowait"); - assertThat(platform.withForUpdate("X", Query.ForUpdate.BASE, Query.LockType.Default)).isEqualTo("X for no key update"); + assertThat(platform.withForUpdate("X", Query.LockWait.SKIPLOCKED, Query.LockType.Default)).isEqualTo("X for no key update skip locked"); + assertThat(platform.withForUpdate("X", Query.LockWait.NOWAIT, Query.LockType.Default)).isEqualTo("X for no key update nowait"); + assertThat(platform.withForUpdate("X", Query.LockWait.WAIT, Query.LockType.Default)).isEqualTo("X for no key update"); } }