Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

counter_cache destroy concurrency issues

#1134

You have the PostController, you are loading data into a variable to destroy it. For example two processes want to destroy the same post. One of them are getting data from the load_post and the second one got the same object of the post. They trying to destroy and no exception will be thrown, and the counter in topic will be decremented twice.


before_filter :load_post

def destroy
  @post.destroy
end

def load_post
  @post = Post.find_by_id(params[:id])
end

class Topic
  has_one :posts, :dependent => :destroy
end

class Post
  belongs_to :topic, :counter_cache => true
end

class CounterCacheConcurrencyTest < Test::Unit::TestCase
  def test_counter_cache_concurrency_test
    t = Topic.new

    posts_count_old = t.posts_count

    t.posts << Post.create



    p = t.posts.first
    p.destroy
    p.destroy

    # Will be failed, because destroy will invoke decrement_counter twice
    # and the actual value will be -1
    assert_equal posts_count_old, t.posts_count
  end
end

Could be fixed by adding an invoke of the after_filter, if destroy will affect at least one record in the database.

Reported by Dmitry Polushkin · September 29th, 2008 @ 01:26 PM

State: wontfix
Milestone: 2.x
Assigned to: Pratik Pratik
Importance: none

Activity

  1. Dmitry Polushkin
    Dmitry Polushkin

    You can also read about this bug on the ruby forum: http://www.ruby-forum.com/topic/...

    Thanks, Dmitry from Estonia

    September 29th, 2008 @ 01:28 PM

  2. Dmitry Polushkin
    Dmitry Polushkin

    Attached patch. No tests yet.

    September 29th, 2008 @ 10:45 PM

  3. Dmitry Polushkin
  4. Dmitry Polushkin
    Dmitry Polushkin
    • Tag changed from affected, before, concurrency, counter_cache, destroy, minus, negative, rows, synchronization to activerecord, affected, before, concurrency, counter_cache, destroy, minus, negative, patch, rows, synchronization
    • Assigned user changed from Tarmo Tänav to DHH

    December 19th, 2008 @ 11:22 AM

  5. Pratik
    Pratik
    • Assigned user changed from DHH to Pratik
    • State changed from new to wontfix

    The patch doesn't really solve the actual issue as @affected_rows_destroy is just an instance variable of the AR object. Best way is to use AR provided locking mechanism.

    Thanks.

    March 6th, 2009 @ 07:32 PM

  6. Dmitry Polushkin
    Dmitry Polushkin

    Pratik

    Can you demonstrate how this could be done through locking mechanism?

    Thanks

    March 11th, 2009 @ 06:05 PM

  7. Pratik