This project is archived and is in readonly mode.
counter_cache destroy concurrency issues
Reported by Dmitry Polushkin | September 29th, 2008 @ 01:26 PM | in 2.x
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.
Comments and changes to this ticket
-
Dmitry Polushkin September 29th, 2008 @ 01:28 PM
You can also read about this bug on the ruby forum: http://www.ruby-forum.com/topic/...
Thanks, Dmitry from Estonia
-
Dmitry Polushkin December 19th, 2008 @ 11:22 AM
- 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
-
Pratik March 6th, 2009 @ 07:32 PM
- 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.
-
Dmitry Polushkin March 11th, 2009 @ 06:05 PM
Pratik
Can you demonstrate how this could be done through locking mechanism?
Thanks
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>