counter_cache concurrency issues; seeking feedback on potential solution

We've run across the following concurrency issue with the has_many :counter_cache option:

We have an Post model that has_many Recommendations and uses a counter_cache:

class Post < ActiveRecord::Base   has_many :recommendations, :counter_cache => true end

And, in a controller, we have a delete_recommendation action:

def delete_recommendation   r = Recommendation.find(params[:id])   r.destroy end

Most of the time, the recommendation counter is updated properly. But if many delete_recommendation requests are processed at once for the same recommendation object, then our counts can get out of sync. The problem is that, in many of the simultaneous requests, the Recommendation.find(params[:id]) line successfully retrieves the object, and is therefore able to call destroy on it. Obviously only one of the resultant "DELETE FROM" SQL calls will actually remove any rows from the database, but the before_destroy callback will be called for every request regardless, which means the count will be improperly decremented multiple times.

There are many ways to work around this problem, but this particular pattern is common, and it seems like the Rails counter_cache implementation ought handle this case. One possible solution:

* Move the counter_cache decrement from the before_destroy callback to the after_destroy callback * Only call the after_destroy callback if the call to destroy actually deleted rows from the database (i.e., rows affected > 0)

Does this behavior sound reasonable? Are there any scenarios where you would want the after_destroy callback to be called even if destroy did not delete anything from the database? Or is there a better solution?

Michael