In an attempt to improve the locking situation, I added a 'Version' column 
to my case class table so NHibernate can get an exclusive lock on it when 
it updates the version.  However, I still have a deadlock, and it's almost 
identical.  The only difference in terms of my original deadlock graph is 
that process 85 now owns an exclusive (X) lock on the base-class table 
(tblOrders) instead of an update (U) lock.

But the deadlock appears to be happening because NHibernate is not 
acquiring *any* lock on the subclass table (tblCustomerOrders).

Using SQL Server Profiler to trace my statements and deadlocks, this 
appears to be the order of things:

   1. [85] SELECT ... FROM tblOrders WITH (updlock,rowlock) INNER JOIN 
   tblCustomerOrders ...
      - This gives [85] an "S" on tblCustomerOrders and an "U" on tblOrders
      2. [85] UPDATE tblOrders SET Version=3 ...
      - This upgrade's [85]'s "U" lock on tblOrders to an "X" lock
   3. [89] SELECT ... FROM tblOrders WITH (updlock,rowlock) INNER JOIN 
   tblCustomerOrders ...
      - This statement starts by obtaining an "S" lock on 
      tblCustomerOrders, but then...
      - it's blocked trying to get a "U" lock on tblOrders (because of 
      statement #1 above)
      - Meanwhile...
   4. [85] UPDATE tblCustomerOrders ...
      - This requires [85] to request an "X" lock on tblCustomerOrders 
      where it previously only had a "S" lock.  But it can't because statement 
#3 
      has an "S" lock on it.
   
Hence [85] and [89] are deadlocked, just as before the optimistic locking 
(that only introduced statement #2).

Now John Davidson posted in a thread ("Dirty optimistic locking") back in 
August 2011 that locking on subclass tables is purposely not done so as to 
avoid deadlocks.  But I'm encountering deadlocks, I think, specifically 
because the subclass tables *aren't* locked.

Am I thinking correctly?  Is there a way out?

Regards,
Brian.

On Monday, January 7, 2013 10:34:26 AM UTC-5, Trinition wrote:
>
> I'm trying to use LockMode to make sure the entity I get through my 
> session locks the row(s) in the database.  However, the generated SQL (for 
> MS SQL Server) appears to only be locking the base row.  This leads to 
> deadlocks when NHibernate eventually updates the properties in the subclass 
> mapping to the child table's row.
>
> I fetch the entity through the session like this:
>
>       CustomerOrder myCustomerOrder = 
> mySession.Get<CustomerOrder>(myCustomerOrderId, LockMode.Upgrade);
>
>  Customer order is a subclass of the Order base class, mapped with 
> table-per-subclass:
>
>       class Order {} // tblOrders
>
>       class CustomerOrder : Order {} // tblCustomerOrders
>
> The generated SQL (observed via NHProf) is:
>
>       SELECT ... 
>
>       FROM   dbo.tblOrders customeror0_ *with (updlock, rowlock)* 
>
>              inner join dbo.tblCustomerOrders customeror0_1_ 
>
>                on customeror0_.OrderID = customeror0_1_.OrderIDID
>
> What I *think* I need is for the "(updlock, rowlock) to also follow 
> tblCustomerOrders (here's one source: 
> http://stackoverflow.com/questions/2577337/can-i-lock-a-record-from-a-join-sql-statment-using-rowlock-updlock
> ).
>
> So if that is what is needed so that the *entity* is locked, shouldn't 
> NHibernate be doing this?
> -- 
> Regards,
> Brian. 
>

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/nhusers/-/fNalwUgQ5NUJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to