DPC Zettelkasten Open in the explorer

Optimistic Locking

Every mutable record carries a version column; a write that does not match the version it read is rejected rather than silently overwriting.

Nearly every persisted record in Medieval Factions — Faction, player, Law, Gate, Locked Block — carries an integer version. It is not domain data; it is a concurrency protocol.

The protocol

UPDATE mf_faction
   SET ..., version = :version + 1
 WHERE id = :id
   AND version = :version

If the row's version has moved since it was read, the WHERE matches nothing, the affected-row count is zero, and the repository throws OptimisticLockingFailureException. The Service Layer maps that to a CONFLICT failure, which a command turns into "someone else changed this, try again".

Why optimistic rather than locked

Two properties of the plugin make this the right trade:

Pessimistic locking would also mean holding a database transaction open across game logic, and game logic on a Bukkit server runs on the main thread. A held lock there is a stalled server.

Failing loudly beats a lost update

The alternative to rejecting the write is accepting it, which silently discards whatever the other writer did. For a Faction record — carrying the roster, the roles, and the flags — a lost update means a player's changes vanish with no error anywhere. A CONFLICT a player can retry is a much better failure.

Because roles and flags live inline on the faction record, editing either bumps the same version as renaming the faction. Fine-grained concurrent edits within one faction are therefore not possible by design.

Sources

Linked from