-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Pessimistic lock with flush
PostPosted: Wed Jun 07, 2006 6:32 am 
Beginner
Beginner

Joined: Wed May 03, 2006 5:10 am
Posts: 32
Location: Monopoli - Italy
Hi,

in the online documentation, inside the paragraph Optimistic concurrency control I have found:


The only approach that is consistent with high concurrency and high scalability is optimistic concurrency control with versioning. NHibernate provides for three possible approaches to writing application code that uses optimistic concurrency.


The first possible approach is the following:

Code:
transaction = session.BeginTransaction();
foo.Property = "bar";
session.Flush();
transaction.Commit();
session.Disconnect();


Applying this approch I note that between the commands
session.Flush() and transaction.Commit()
the system applies a pessimistic lock.

In my application for saving a collection (I need to save only single items under certain conditions) I have multiples

Code:
_session.SaveOrUpdate(entity);
_session.Flush();


and only one transaction.Commit(), at the end.
So my application is under pessimistic lock between the first session.Flush() and the final transaction.Commit().
The time is proportional to the collection lenght.

Someone can suggest me a way to avoid this problem?


Thanks
Antonella


Top
 Profile  
 
 Post subject: Re: Pessimistic lock with flush
PostPosted: Wed Jun 07, 2006 7:10 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
antoska wrote:
Hi,
Code:
_session.SaveOrUpdate(entity);
_session.Flush();


and only one transaction.Commit(), at the end.
So my application is under pessimistic lock between the first session.Flush() and the final transaction.Commit().
The time is proportional to the collection lenght.

Someone can suggest me a way to avoid this problem?


The obvious answer is: Do not call _session.Flush() after each _session.SaveOrUpdate, but only once before tarnsaction.Commit();

The session.Flush is intended to execute update/insert/delete SQL statements and I see no way to prevent SQL engine to apply pessimistic locks for manipulated data.

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 07, 2006 8:39 am 
Beginner
Beginner

Joined: Wed May 03, 2006 5:10 am
Posts: 32
Location: Monopoli - Italy
Yes,

but Flush() in that position solved me 2 kind of problems (I'm working in a romoting context).


Moving Flush() before transaction commit:

1)

Code:
LoadCollection()

collItem[i].description = "xxx";

int rowVersionBefore = collItem[i].RowVersion;

collection.SaveOrUpdate(); --> this method contains transaction management and saveOrUpdate is called in a iteration on each changed collection item

int rowVersionAfter = collItem[i].RowVersion;


rowVersionBefore and rowVersionAfter have the same value

2)

Code:
LoadCollection()

collItem[i].description = "xxx";

int rowVersionBefore = collItem[i].RowVersion;

collection.SaveOrUpdate(); --> this method contains transaction management and saveOrUpdate is called in a iteration on each changed collection item

int rowVersionAfter = collItem[i].RowVersion;

collItem[i].description = "yyy";
collection.SaveOrUpdate();



the second SaveOrUpdate() throws an exception of
Row was updated or deleted by another transaction because the single item is not refreshed

Antonella


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 07, 2006 2:34 pm 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
antoska wrote:
Code:
LoadCollection()

collItem[i].description = "xxx";

int rowVersionBefore = collItem[i].RowVersion;

collection.SaveOrUpdate(); --> this method contains transaction management and saveOrUpdate is called in a iteration on each changed collection item

int rowVersionAfter = collItem[i].RowVersion;


rowVersionBefore and rowVersionAfter have the same value


This is as expected. As the changes are not sent to database, RowVersion is updated yet.

antoska wrote:
Code:
LoadCollection()

collItem[i].description = "xxx";

int rowVersionBefore = collItem[i].RowVersion;

collection.SaveOrUpdate(); --> this method contains transaction management and saveOrUpdate is called in a iteration on each changed collection item

int rowVersionAfter = collItem[i].RowVersion;

collItem[i].description = "yyy";
collection.SaveOrUpdate();



the second SaveOrUpdate() throws an exception of
Row was updated or deleted by another transaction because the single item is not refreshed


Let me guess: the items are MarshalByValue objects? What about the collection? Also MarshalByValue? Have You verified where is the transaction handling code (start/commit) executing, inside client or inside server process? If on client, then it does not sound to be very good.. Anyway, make sure You understand which calls are going to be remoted and which ones not. Otherwise You are not able to design an effective system.

All my remoting is done trough Web Service methods, or similar service interfaces. Service interface gives very strong feeling what happens on server and what on server side.. Anyway, as result, I have no experience with "chatty" remoting programming, and I can't give much advice here. (Expect to switch over to chunky remoting ;) - it performs and scales better)

Gert

_________________
If a reply helps You, rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 08, 2006 4:21 am 
Beginner
Beginner

Joined: Wed May 03, 2006 5:10 am
Posts: 32
Location: Monopoli - Italy
Hi,

thanks for your response.


gert wrote:
This is as expected. As the changes are not sent to database, RowVersion is updated yet.


It isn't exact. The changes are already sent to the database, because inside the method collection.SaveOrUpdate() I start and commit my transaction.

gert wrote:
Let me guess: the items are MarshalByValue objects? What about the collection? Also MarshalByValue?


Yes, both objects are MarshalByValue.

gert wrote:
Have You verified where is the transaction handling code (start/commit) executing, inside client or inside server process? If on client, then it does not sound to be very good..


The method SaveOrUpdate calls a proxy object that executes every operation related to the db on the server.

Thanks,

Antonella


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.