[jOOQ/jOOQ#10050] Add support for optimistic locking with UpdatableRecord.merge()

This commit is contained in:
Lukas Eder 2020-04-08 10:29:01 +02:00
parent 01c58467e7
commit c3de72f537
2 changed files with 35 additions and 3 deletions

View File

@ -376,6 +376,16 @@ public class TableRecordImpl<R extends TableRecord<R>> extends AbstractRecord im
return result;
}
final Object getRecordVersion() {
TableField<R, ?> field = getTable().getRecordVersion();
return field != null ? get(field) : null;
}
final Object getRecordTimestamp() {
TableField<R, ?> field = getTable().getRecordTimestamp();
return field != null ? get(field) : null;
}
final boolean isUpdateRecordVersion() {
Configuration configuration = configuration();

View File

@ -251,9 +251,31 @@ public class UpdatableRecordImpl<R extends UpdatableRecord<R>> extends TableReco
}
private final int storeMerge0(Field<?>[] storeFields, TableField<R, ?>[] keys) {
InsertQuery<R> merge = create().insertQuery(getTable());
merge.onDuplicateKeyUpdate(true);
return storeMergeOrUpdate0(storeFields, keys, merge, true);
// [#10050] No need for MERGE with optimistic locking being active.
if (lockingActive()) {
if (lockValuePresent())
return storeUpdate0(storeFields, keys);
else
return storeInsert0(storeFields);
}
else {
InsertQuery<R> merge = create().insertQuery(getTable());
merge.onDuplicateKeyUpdate(true);
return storeMergeOrUpdate0(storeFields, keys, merge, true);
}
}
private final boolean lockingActive() {
return isExecuteWithOptimisticLocking() && (isTimestampOrVersionAvailable() || isExecuteWithOptimisticLockingIncludeUnversioned());
}
private final boolean lockValuePresent() {
// [#10050] A lock value is present if we either have locking columns or if the record was fetched from the database
return getRecordVersion() != null
|| getRecordTimestamp() != null
|| getTable().getRecordVersion() == null && getTable().getRecordTimestamp() == null && fetched;
}
private final <Q extends StoreQuery<R> & org.jooq.ConditionProvider> int storeMergeOrUpdate0(Field<?>[] storeFields, TableField<R, ?>[] keys, Q query, boolean merge) {