0

Following is the code snippet I am using to get an optimistic lock.

setting = this.entityManager.find(Setting.class, id, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
setting.setUpdateTimestamp(new Date()); // I want to make sure that this setting is not changed by 
//any other module. So I am updating timestamp so that others will fail.
newSettingList.add(setting);

Now, is there any other way to do this without updating any of the field in an entity and make sure no other module changes that entity in optimistic lock.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
Vrishank
  • 302
  • 4
  • 22
  • Optimistic lock occurs when two or more process access on the same data and try to modify concurrently. Have you checked if multiple processes are modifying the data at same? – Anil Nov 02 '17 at 05:31
  • Yes. There are concurrent processes which CAN change the same setting data. – Vrishank Nov 02 '17 at 05:48
  • does optimistic_force_increment itself alone ensure that the data will not be changed by other process until the locking process commits it? or an update statement is necessary? – Vrishank Nov 02 '17 at 06:03

1 Answers1

0

does optimistic_force_increment itself alone ensure that the data will not be changed by other processes until the locking process commits it?

Depends on what you mean by that. It puts an optimistic lock on that entity. This by definition means others are free to change it and even write it back to the database if the flush their changes before you do. If they do so YOU will get an exception when trying to flush your changes.

If you flush before them, they'll get the exception.

If you want to prevent anybody to write the entity before you commit or rollback you'll need a pessimistic lock.

Regarding repeatable reads optimistic locks give the following guarantee (quote from the JPA Specification):

P2 (Non-repeatable read): Transaction T1 reads a row. Another transaction T2 then modifies or deletes that row, before T1 has committed. Both transactions eventually commit successfully.

Note that everything is allowed until both transaction commit.

Pessimistic locks give this guarantee:

P2 (Non-repeatable read): Transaction T1 reads a row. Another transaction T2 then modifies or deletes that row, before T1 has committed or rolled back.

So here T2 is not allowed to make changes before T1 (the one holding the lock) is done.

Or is an update statement is necessary?

You don't need an explicit update. The *FORCE_INCREMENT lock types include an update of the version column though. So a roundtrip to the database is involved.

Note: I'm writing "flush" all the time because I think that is when the exceptions normally happen, but the specification allows that to happen whenever the JPA implementation feels like it.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348