-
Notifications
You must be signed in to change notification settings - Fork 563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pessimistic locking via add_lock! adds lock clause on nested selects and can cause deadlock #1
Comments
Been busy, sorry for the delay. This looks good, and the change does not break any tests, but a regression test would have been nice. In fact... I'll need one. I can not get a test I tried writing for you to fail. For instance, I did this in pessimistic locking test.
Which results in the following SQL that appears to work.
I need more to go on. Can you help write a failing test? |
Ken, I've been swamped too. I'll try to get back to this and provide you a failing test. |
Ken, we have tracked down the deadlock to something unrelated to the reported issue namely two threads blocking each other: one holding a DB lock, the other executing a blocking operation which needs the row locked by the first thread. With this said, I believe the gsub! is dangerous as I would expect the user would only want to lock the row for the original select and not every table included in the query. I'm not sure how you want to resolve this. |
Thanks. You know what, I've had the same issue too! We have many databases and found that while tests were running and doing all their cross db stuff, we would get deadlocks. Muz added some cool stuff to the adapter that allows you to run in different isolation levels. The method is run_with_isolation_level and it takes a block. In our application, I have a filter in our paginated results controllers, like search/aggregate controllers like this. around_filter :with_uncommitted_isolation_level The implementation in the private root application controller is this.
This means that all of our search and aggregate view controllers are much quicker in the case where other users are writing to those tables. SQL Server waits for any object in transaction in the whole table before a SELECT happens. This totally threw me when I first learned about it. But the :lock option and Muz's addition in the adapter allows us to get around this easily and be kinder on the DB. |
Add SQL Server database tasks
…ls_6_rc2 Upgrade Rails 6
Reported by Joe Rafaniello | June 12th, 2009 @ 05:28 PM
I am using the 2.2.16 version of the adapter and noticed that I occasionally receive deadlocks while using the :lock option, like this:
The error shows itself as a process being chosen as a deadlock victim. Notice that we have nested selects and that each one has a WITH(UPDLOCK,ROWLOCK) and they are on the same table:
I found that the sql.gsub! line in the add_lock! method of the adapter is adding the LOCK phrase to each of the FROM clauses. I have a hack to the adapter to only add the lock for the first select we find. I'm not sure this is really the correct way of handling it. I'm not sure how to handle the JOIN gsub! either. Any ideas?
Attached is a svn diff of my local patch.
http://rails-sqlserver.lighthouseapp.com/attachments/132867/add_lock_deadlock.patch
The text was updated successfully, but these errors were encountered: