module CQL::ActiveRecord::OptimisticLocking

Overview

Provides optimistic locking functionality for Active Record models. This module allows you to prevent concurrent updates from overwriting each other by using a version column in the database.

Usage

Give the table a version column and include this module in the model, naming that column. The lock_version table helper names it version unless told otherwise, while a bare optimistic_locking reads lock_version, so pass version_column::

AppDB = CQL::Schema.define(:app_db, adapter: CQL::Adapter::SQLite, uri: "sqlite3://./app.db") do
  table :documents do
    primary :id, Int64, auto_increment: true
    text :title
    lock_version :version
  end
end

class Document
  include CQL::ActiveRecord::Model(Int64)
  include CQL::ActiveRecord::OptimisticLocking
  db_context AppDB, :documents

  property title : String = ""
  property version : Int32 = 1

  optimistic_locking version_column: :version

  def initialize
  end
end

# When updating a record, a concurrent update is detected:
document = Document.find!(1)
# Somebody else updates this record in another process
begin
  document.update!(title: "New Title") # raises: the version moved on
rescue CQL::OptimisticLockError
  document.reload!                     # Get the latest version
  document.update!(title: "New Title") # Try again
end

Defined in:

active_record/optimistic_locking.cr

Macro Summary

Macro Detail

macro optimistic_locking(version_column = :lock_version) #

Define optimistic locking for a model

  • @param version_column [Symbol] the name of the version column (default: :lock_version)

Example

optimistic_locking version_column: :version

[View source]