Skip to content

Commit 2717f64

Browse files
committed
RMB-992: Don't increment optimistic locking _version when updating non-jsonb columns
Some code like https://folio-org.atlassian.net/browse/MODINVSTOR-1105 https://github.com/folio-org/mod-inventory-storage/pull/926/files maintains an additional derived column like complete_updated_date. Only updates of the jsonb column should trigger an _version increment, not updates of other columns like complete_updated_date. Other columns are derived values and therefore don’t need optimistic locking. If developers manually add a column that requires optimistic locking they can manually adjust the optimistic locking trigger accordingly. Columns not maintained by RMB are out of scope of RMB’s optimistic locking support. (cherry picked from commit cb22ee7)
1 parent 92ac4cb commit 2717f64

4 files changed

Lines changed: 19 additions & 8 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1983,7 +1983,7 @@ RMB is aware of the [metadata.schema](https://github.com/folio-org/raml/blob/ram
19831983

19841984
## Optimistic Locking
19851985

1986-
RMB supports optimistic locking. By default it is disabled. Module developers can enable it by adding attribute `withOptimisticLocking` to the table definition in schema.json. The available options are listed below. Unless `off` is specified, a database trigger will be created to auto populate the `_version` field in json on insert. On update a database trigger will check that the `_version` field is the same in the incoming record and in the database, and will then increment the `_version` field before updating the database record. Note, `_version` field has to be defined in json to make this work. PgUtil reports a version conflict error as 409 HTTP response code if 409 is defined in RAML, otherwise, it will fall back to use 400 or 500 HTTP response code. The client should never increment the `_version` property; only the trigger should increment it to ensure that the check and the increment are in the same transaction to avoid any race condition.
1986+
RMB supports optimistic locking. By default it is disabled. Module developers can enable it by adding attribute `withOptimisticLocking` to the table definition in schema.json. The available options are listed below. Unless `off` is specified, a database trigger will be created to auto populate the `_version` field in json on insert. On jsonb column update a database trigger will check that the `_version` field is the same in the incoming record and in the database, and will then increment the `_version` field before updating the database record. Note, `_version` field has to be defined in json to make this work. PgUtil reports a version conflict error as 409 HTTP response code if 409 is defined in RAML, otherwise, it will fall back to use 400 or 500 HTTP response code. The client should never increment the `_version` property; only the trigger should increment it to ensure that the check and the increment are in the same transaction to avoid any race condition.
19871987

19881988
* `off` Optimistic Locking is disabled. The trigger is removed if it existed before.
19891989
* `failOnConflict` Optimistic Locking is enabled. Version conflict will fail the transaction with a customized SQL error code 23F09.

domain-models-runtime/src/main/resources/templates/db_scripts/optimistic_locking.ftl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
DROP TRIGGER IF EXISTS set_${table.tableName}_ol_version_trigger
4040
ON ${myuniversity}_${mymodule}.${table.tableName} CASCADE;
4141

42-
CREATE TRIGGER set_${table.tableName}_ol_version_trigger BEFORE INSERT OR UPDATE
42+
CREATE TRIGGER set_${table.tableName}_ol_version_trigger BEFORE INSERT OR UPDATE OF jsonb
4343
ON ${myuniversity}_${mymodule}.${table.tableName}
4444
FOR EACH ROW EXECUTE PROCEDURE ${myuniversity}_${mymodule}.${table.tableName}_set_ol_version();
4545

domain-models-runtime/src/test/java/org/folio/rest/persist/ddlgen/SchemaMakerIT.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ public void canCreateOptimisticLockingTrigger(TestContext context) {
424424
});
425425
assertVersion(context, 0, 1, 1, 1);
426426

427-
// test update
427+
// update of jsonb column
428428
tables.forEach(table -> {
429429
String updateSql = "UPDATE " + table + " SET jsonb=jsonb_set(jsonb, '{_version}', to_jsonb('2'::text))";
430430
if (table.equals("tab_ol_fail") || table.equals("tab_ol_fail_suppress")) {
@@ -436,6 +436,12 @@ public void canCreateOptimisticLockingTrigger(TestContext context) {
436436
});
437437
assertVersion(context, 2, 2, 1, 1);
438438

439+
// update of created_by column should not touch _version
440+
tables.forEach(table -> {
441+
execute(context, "UPDATE " + table + " SET created_by='foo'");
442+
});
443+
assertVersion(context, 2, 2, 1, 1);
444+
439445
// test insert with provided _version
440446
tables.forEach(table -> {
441447
execute(context, "DELETE FROM " + table + "; "

domain-models-runtime/src/test/resources/templates/db_scripts/schemaWithOptimisticLocking.json

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,27 @@
22
"tables": [
33
{
44
"tableName": "tab_ol_off",
5-
"withOptimisticLocking": "off"
5+
"withOptimisticLocking": "off",
6+
"withMetadata": true
67
},
78
{
89
"tableName": "tab_ol_log",
9-
"withOptimisticLocking": "logOnConflict"
10+
"withOptimisticLocking": "logOnConflict",
11+
"withMetadata": true
1012
},
1113
{
1214
"tableName": "tab_ol_fail",
13-
"withOptimisticLocking": "failOnConflict"
15+
"withOptimisticLocking": "failOnConflict",
16+
"withMetadata": true
1417
},
1518
{
1619
"tableName": "tab_ol_fail_suppress",
17-
"withOptimisticLocking": "failOnConflictUnlessSuppressed"
20+
"withOptimisticLocking": "failOnConflictUnlessSuppressed",
21+
"withMetadata": true
1822
},
1923
{
20-
"tableName": "tab_ol_none"
24+
"tableName": "tab_ol_none",
25+
"withMetadata": true
2126
}
2227
]
2328
}

0 commit comments

Comments
 (0)