In a Rails 5 app I create items and increment their position:
class ListItem < ActiveRecord::Base
  belongs_to :list
  before_validation :ensure_position
  private
  def ensure_position
    self.position ||= self.class.where(list_id: list_id).maximum(:position).to_i + 1
  end
end
The index responsible for the duplicate violation is:
 t.index ["list_id", "position"]
I get a PG duplicate key violation on the :position column. Whenever multiple create are fired simultaneously, the maximum function returns the same position for multiple records.
I am new to thread safety and postgres locking in ruby on rails. Is there a way to lock or create a mutex on save action of the list item record so that the position gets incremented safely?
 
    