Locking problem

Posts   
 
    
gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 29-Apr-2008 10:08:19   

Hi folks,

I've ran in to the following problem:

I want to update some related entities after a Save has completed, so I decided to override OnSaveComplete() in the entities and call the methods that perform these update actions.

Till now this has never been a problem, but now (i guess for the first time) some of the methods that do the update actions need to do some select statements on the table of which the just saved entity is a part. The problem here is that after the base.OnSaveComplete() the table of the entity that was just saved still seems to have a lock on it. Therefore my update logic waits for the lock to come free, but it never does, since the unlocking is waiting on the update logic to be finished.

So it seems this is not the right location for such an action. Am I abusing OnSaveComplete wrongly or do I need to perform some other method to place any logic just after the lock has been freed.

Any help would be greatly appreciated!

Thanks, Gab

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 29-Apr-2008 10:23:14   

The problem here is that after the base.OnSaveComplete() the table of the entity that was just saved still seems to have a lock on it

You should look for the source of this lock. (Use the database profiler for example). Is the parent entity saved inside a transaction? Are you trying to save it within a collection for instance? Is it part of an inheritance hierarchy?

Would you please post the saving code?

mdbruning
User
Posts: 18
Joined: 10-Mar-2008
# Posted on: 19-May-2008 15:32:27   

I'm dealing with this issue as well.

I've overridden the OnSaveComplete method to do some logic after an entity has been saved to the persistent storage.

The situation is as follows:

I am saving an OrderEntity instance using order.Save(true);

I have overridden the OnSaveComplete method of my OrderEntity class. In this overridden method I am checking if related records exist (which should be).

Because I am saving the OrderEntity instance recursively, the related OrderItemCollection (1:n) is also being saved.

My OrderItemValidator class (which is injected) does some checks in the overridden ValidateEntityBeforeSave method. These checks also consist of fetching an OrderCollection.

Here's where the database lock is kicking in.

I figured out the following steps (don't know if it's correct):

  • First, the order is recursively being saved and a database lock is on the Order table
  • Second, the order items are being saved because of the recursive save of the order
  • While the order items are being saved, some logic is being executed by an OrderItemValidator class using injectables. This logic consists of fetches from the Order table. But the lock is still on the Order table from the first step, so a deadlock is created.

How to handle with this situation?

FYI: the foreign keys in the tables are all set to enforce foreign key constraints. If these constraints are being disabled, then the situation works. But that's not my intention.

Perhaps you can tell me if the following is correct as well: it looks like that when the OnSaveComplete method is being called, a lock still is set on the table.

In my example, I've set a breakpoint in first line of the overridden OnSaveComplete method. When I try to open the table in the SQL Server Management Studio, a lock exists on the table and I can't see the data contents of the table.

Wouldn't it be logical that when the OnSaveComplete method is being called, the save is completed and the lock is released? Or I am doing something terribly wrong? confused

Thanks in advance! Mathieu

mdbruning
User
Posts: 18
Joined: 10-Mar-2008
# Posted on: 19-May-2008 15:40:24   

Perhaps it's better to use the AfterSave event instead of override the OnSaveComplete method?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 19-May-2008 18:36:33   

You can fetch entities in a save action, but you have to add the entity instances you're fetching or the collection you're fetching to the active transaction (entity.Transaction) of the entity. Otherwise you will get deadlocks.

Frans Bouma | Lead developer LLBLGen Pro
gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 19-May-2008 22:22:04   

Thanks for the info, we will be trying this soon!

gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 20-May-2008 17:54:28   

This worked.