My application is widely used touchto take advantage of the Rails template caching system. There is a certain work that my application does when many relationships are created between many different objects in a package. Sometimes some of this work leads to a cascading touches resulting in a dead end.
I can create code around this script where I see this happening often, but seeing that it has revealed a big problem that can happen in other scripts, although this is very unlikely.
To understand this, think of two people following each other on Twitter at exactly the same moment. They both click "Follow", which creates interconnected objects between them, and then each of their touched entries . If these strokes are intertwined:
- process 1 concerns user A
- process 2 concerns user B
- process 1 concerns user B
- process 2 concerns user A
Each process uses a database transaction, so this will lead to a deadlock.
Am I really mistaken that this can happen in the normal operation of an application outside of my strange batch scenario? If I am not mistaken, is there a solution? Can I move touches out of a transaction in any way ? (Last Write Wins is great for updating updated_at anyway ...)
update -
class Follow
belongs_to :follower, touch: true
belongs_to :followee, touch: true
end
@u1 = User.find(1)
@u2 = User.find(2)
Follow.create!(follower: @u1, followee: @u2)
Follow.create!(follower: @u2, followee: @u1)