Disclaimer: I'm a several-year NHibernate user, but have only barely 
dabbled in extending it through code (a listener here, a custom type 
there).  I think I may be able to solve my deadlock through some more 
involved NHibernate custom code.

I'm currently encountering a deadlock caused when I started Upgrade locking 
the joined-subclass entities I was updating.  From what I've discovered on 
my own thus far, I believe my problem stems from the fact that *only* the 
base class' table is locked, not the joined subclass' table (details in 
nhusers post: 
https://groups.google.com/forum/?fromgroups=#!topic/nhusers/6857P97StD8).

In the *nhusers *forum, one *John Davidson* said that locking only the base 
class table is on purpose to avoid possible deadlock if the subclass table 
were to be locked.  There's even comments on *Lockable* to this effect. 
 However, I'm encountering a deadlock, I believe, because *only* the base 
class table is locked.  I find myself wondering if the statement about 
locking the base class' table was really about locking it *instead of* the 
subclass' table, whereas locking both the base class' table and subclass' 
table might not be susceptible to the deadlocks that lead to that policy in 
the first place.

Further, it seems there are some Hibernate inconsistencies (HHH-5436 
https://hibernate.onjira.com/browse/HHH-5436) where, depending on which 
strategy you use for asking Hibernate to lock your entities, it may lock 
just the base class' table, or both tables.  This is similar to my 
experience in that NHibernate's (and, indeed, Hibernate's) locking of 
joined tables is inconsistent depending on whether the underlying database 
syntax uses the per-table "WITH xxxlock" syntax (like MsSql) or the 
statement-level "FOR UPDATE" syntax (like Oracle).

I believe what I want to try is customizing enough of NHibernate so that 
the SQL for getting a subclass entity from the session locks both tables in 
MS SQL, e.g.:

SELECT ... FROM tblOrders WITH (updlock,rowlock) INNER JOIN 
tblCustomerOrders WITH (updlock,rowlock) ...;


...where the updlock is added to the subclass table's name, as well.  I 
started looking at the *MsSql2008Dialect* hierarchy and see how it applies 
lock hints to table names; however, it seems the decision over which table 
name to apply the lock hint names to isn't the dialect's, but elsewhere. I 
think I may have found the responsible code in *
AbstractEntityJoinWalker.InitStatementString(...)*.  That method explicit 
asks the dialect to append the lock hint to the base class' table, but 
never the joined tables.  

I could've handle subclassing my own dialect to tweak a few things, but 
since that won't do it, I think the next level up is the whole *Persister*, 
a much bigger job.  Is there some other level in-between that is more 
suitable for trying what I want to try?

Reply via email to