I'm confused about checkin 1879: "Do not invoke the busy callback when trying to promote a lock from SHARED to RESERVED. This avoids a deadlock."
Consider two threads that are deadlocking. Thread A has made changes, and is preparing to commit, so promotes its lock from reserved to pending. Thread B begins making changes, and wants to promote its lock from shared to reserved. At that point, no more progress can be made. Thread A can't go from pending to exclusive because B still has a shared lock. Thread B can't go from shared to reserved because Thread A has a pending lock. My experience with the code up to 3.0.3 is that both thread A and B will begin calling the busy handler. I've written my application so that my busy handler can choose which thread to force to rollback, using application-specific knowledge about the precedence of the threads (UI threads are given preference, and background threads roll back). It may happen that thread A is actually a background thread, so even if it has the more advanced lock, I will choose to roll it back, letting thread B continue on. With the change in checkin 1879, it looks like my busy handler doesn't get a chance to make a choice any more. Now thread B immediately gets a BUSY error, without invoking the busy handler. Personally, I was very pleased that the busy handler allowed me so much control. I can see the other side of the argument: for users who don't want to be bothered implementing a fancy busy handler, the fewer deadlocks the better. My application will continue to work (because all threads are prepared for deadlock errors), but I liked being able to make an intelligent choice. Wouldn't it be better to invoke the busy handler in all cases? Have I gotten something wrong? --Ned. http://nedbatchelder.com