Selective optimistic locking

I’m working on a photo gallery and use optimistic locking to prevent
concurrent editing of photo description.
At the same time I want to gather view statistics, incrementing a
counter every time a user views a larger version of a photo.

There are two solutions that came to my mind:

  • split photo into two models: description and statistics,
  • update view count without increasing lock_version.

The first one is a bit troublesome (I’d need to maintain a real 1 : 1
relationship, not a 1 : 0 … 1), so I decided to implement the second.

My problem is that there’s no easy and documented way to do this.
Here’s my solution:

(in the Photo model)
def increment_view_count!
Photo.transaction do
lock!
# optimistic lock must by turned off for this update
increment(:views)
update_without_lock
end
end

update_without_lock is defined in ActiveRecord::Locking::Optimistic,
it’s an alias to original update from ActiveRecord::Base, afaik.

This allows a privileged user to edit a photo and others may increase
the view count at the same time.

Could you comment on this? Maybe you have some other ideas?

Marcin S.

Marcin S. wrote:

def increment_view_count!
Photo.transaction do
lock!
# optimistic lock must by turned off for this update
increment(:views)
update_without_lock
end
end

If you don’t need to read the current view count when
incrementing, an alternative is:

def increment_view_count!
Photo.increment_counter(:views, id)
end


We develop, watch us RoR, in numbers too big to ignore.

Mark Reginald J. wrote:

Marcin S. wrote:

def increment_view_count!
Photo.transaction do
lock!
# optimistic lock must by turned off for this update
increment(:views)
update_without_lock
end
end

If you don’t need to read the current view count when
incrementing, an alternative is:

def increment_view_count!
Photo.increment_counter(:views, id)
end

Good point, thanks.


Marcin S.