-->
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.  [ 4 posts ] 
Author Message
 Post subject: BeginTransaction(IsolationLevel.RepeatableRead) don't work
PostPosted: Sun Oct 02, 2005 1:20 pm 
Newbie

Joined: Wed Sep 28, 2005 1:16 pm
Posts: 4
Code:
ISessionFactory _factory = SessionFactory.GetInstance().GetNHibernateFactory();

ISession activeSession1 = _factory.OpenSession();
ISession activeSession2 = _factory.OpenSession();
         
ITransaction  transaction1= activeSession1.BeginTransaction(IsolationLevel.RepeatableRead);
ITransaction  transaction2= activeSession2.BeginTransaction(IsolationLevel.RepeatableRead);

Customer customer1 = activeSession1.Load(typeof (Customer), 3) as Customer;
Customer customer2 = activeSession2.Load(typeof (Customer), 3) as Customer;
customer1.EMail = "customer1@email.com";
customer2.EMail ="customer2@email.com";
activeSession2.Update(customer2);
transaction2.Commit();
activeSession1.Update(customer1);
transaction1.Commit();


code will raise a sqlclient.SqlException for sql time out on activeSession2.Update(customer2);

but I dont know why code wont be block on activeSession2.Load.
I have also tried activeSession1.Load(typeof (Customer), 3, LockMode.Upgrade), but still cant prevent other session to read.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 04, 2005 10:31 am 
Regular
Regular

Joined: Mon May 16, 2005 1:35 am
Posts: 67
customer1 and customer2 have the same database identity - they refer to the same record. SQL Server enforces transaction isolation through record locks. Therefore, once customer ID 3 is read in transaction1, a HOLDLOCK is placed on the record. transaction2 then goes and places another HOLDLOCK on the same record.

The HOLDLOCK from transaction1 prevents the update attempted through transaction2 until transaction1 commits or rolls back. So, the activeSession2.Update(customer2) statement times out because the transaction1.Commit() statement is after the activeSession2.Update(customer2) statement.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 10, 2005 11:14 am 
Newbie

Joined: Wed Sep 28, 2005 1:16 pm
Posts: 4
I notice that lock don't work with sql server 2000.
Code:
  public override bool SupportsForUpdate
  {
     get { return false; }
  }

Sql server 2000 use another way to lock database.
NHibernate base on Hibernate. In java world Maybe no one think sopport
sql server is important thing. But it is nightmare in .Net world.

At first I wannt to use Session.Lock() to lock object. Because I use
Per-Request/Pre-Session. Object will be edited by 2 or more session.
But I find it is no use on SQL server 2000. So I have to use
BeginTransaction(IsolationLevel.RepeatableRead);

A exception will be raised though it can prevent data confusion.
I think I just need block other session read an object for a short time.
How to do?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 10, 2005 3:19 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
The RepeatableRead solution would actually work in the real situation. In your example you just created an artificial deadlock and you are complaining that it actually deadlocks :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.