-->
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.  [ 6 posts ] 
Author Message
 Post subject: select for update with Sybase
PostPosted: Wed Aug 11, 2004 5:32 am 
Expert
Expert

Joined: Thu Jan 29, 2004 2:31 am
Posts: 362
Location: Switzerland, Bern
Hi

From the SybaseDialect class I can see that select for update and select for update no wait ins't suportetd. Does this mean that if I do session.lock(anId, LockMode.UPGRADE) I do not really get the pessimstic lock I'm looking for? Form the code I found in AbstractEntityPersister.initLockers(), I think for Sybase the instance is just "selected" again without acquiering any locks.

AFAIK in Sybase the "for update" is called holdlock which means the SQL should look like this
Code:
select PID from TABLE_A holdlock where PID =? and SYSTEM_ID =?


Unfortunately I don't have a Sybase DB at hand to test this. The test you find below is done using MySql.

Best Regards
Ernst


Hibernate version: 2.1.4

Mapping documents:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
   <class name="hello.ClassA" table="TABLE_A">
      <composite-id name="pk" class="hello.CapiPK">
         <key-property name="pid" column="PID"/>
         <key-property name="systemId" column="SYSTEM_ID"/>
      </composite-id>
      <set name="B" table="TABLE_B" cascade="all" inverse="true">
         <key>
            <column name="A_PID"/>
            <column name="SYSTEM_ID"/>
         </key>
         <one-to-many class="hello.ClassB"/>
      </set>
      <set name="C" table="TABLE_C" cascade="all" inverse="true">
         <key>
            <column name="A_PID"/>
            <column name="SYSTEM_ID"/>
         </key>
         <one-to-many class="hello.ClassC"/>
      </set>
   </class>
</hibernate-mapping>



Code between sessionFactory.openSession() and session.close():
Code:
      session = sf.openSession(new CapiInterceptor());
      tx = session.beginTransaction();
      
      a = (ClassA) session.load(ClassA.class, a.getPk());
      System.out.println("asking for lock ***********************************************");
      session.lock(a, LockMode.UPGRADE);
      System.out.println("has lock ***********************************************");
      Set as = a.getB();
      for (Iterator iter = as.iterator(); iter.hasNext();) {
            ClassB element = (ClassB) iter.next();
            element.setPayload("Hugo Habicht");
        }
      
      tx.commit();
      session.close();


Full stack trace of any exception that occurs:
no exceptions thrown

Name and version of the database you are using:
MySQL 4.0.20a

Debug level Hibernate log excerpt:
Code:
...
Hibernate: select classa0_.PID as PID0_, classa0_.SYSTEM_ID as SYSTEM_ID0_ from TABLE_A classa0_ where classa0_.PID=? and classa0_.SYSTEM_ID=?
Hibernate: select c0_.PID as PID__, c0_.SYSTEM_ID as SYSTEM_ID__, c0_.A_PID as A_PID__, c0_.PID as PID0_, c0_.SYSTEM_ID as SYSTEM_ID0_, c0_.A_PID as A_PID0_, c0_.SYSTEM_ID as SYSTEM_ID0_ from TABLE_C c0_ where c0_.A_PID=? and c0_.SYSTEM_ID=?
Hibernate: select b0_.PID as PID__, b0_.SYSTEM_ID as SYSTEM_ID__, b0_.A_PID as A_PID__, b0_.PID as PID0_, b0_.SYSTEM_ID as SYSTEM_ID0_, b0_.A_PID as A_PID0_, b0_.SYSTEM_ID as SYSTEM_ID0_, b0_.payload as payload0_ from TABLE_B b0_ where b0_.A_PID=? and b0_.SYSTEM_ID=?
asking for lock ***********************************************
Hibernate: select PID from TABLE_A where PID =? and SYSTEM_ID =? for update
has lock ***********************************************
Hibernate: update TABLE_B set A_PID=?, payload=? where PID=? and SYSTEM_ID=?
...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 11, 2004 5:36 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Why not produce a patch for SybaseDialect and submit to JIRA.

This is how it is implemented on SQLServerDialect:

Code:
   public String appendLockHint(LockMode mode, String tableName) {
      if ( mode.greaterThan(LockMode.READ) ) {
         return tableName + " with (updlock, rowlock)";
      }
      else {
         return tableName;
      }
   }


you just have to override that one method.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 11, 2004 5:41 am 
Expert
Expert

Joined: Thu Jan 29, 2004 2:31 am
Posts: 362
Location: Switzerland, Bern
I'll give it a try as soon I have a Sybase DB running to test it.

Thanks for the detailed help
Ernst


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 11, 2004 5:48 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
don't worry, i figured it out.

i'll commit to CVS, and let you test it out


Top
 Profile  
 
 Post subject: Re: select for update with Sybase
PostPosted: Thu Sep 16, 2004 8:58 am 
Beginner
Beginner

Joined: Fri Nov 21, 2003 4:50 am
Posts: 23
[quote="ernst_pluess"]Hi

AFAIK in Sybase the "for update" is called [i]holdlock[/i] which means the SQL should look like this
[code]select PID from TABLE_A holdlock where PID =? and SYSTEM_ID =?[/code]

[/quote]

Thats not correct. A holdlock is just a shared lock (a shared lock is set on every select and removed after the select). Holdlock only extends this shared lock to the end of the transaction. It is not possible in sybase to just aquire a pessimistic lock. With holdlock you can detect concurrent modification, but you cannot block another process on holdlock (avoid concurrent modification), which is afaik the semantics of select for update. To do this with sybase you must do a dummy update (update ... set id=id).

I don't know, what is planned in hibernate, but my opinion is that it is vital to have a pessimistic locking (select for update) working on every dialect (especially for our project ;-). With the current approach the sybase dialect did not provide such a locking.

Armin


Top
 Profile  
 
 Post subject: Re: select for update with Sybase
PostPosted: Fri Oct 15, 2010 4:43 am 
Newbie

Joined: Fri Oct 15, 2010 4:16 am
Posts: 1
Hi,

I have been trying to get pessimistic locking working with sybase ianywhere.
I think the updlock or xlock table hints should be used:

Code:
public String appendLockHint(LockMode mode, String tableName)
{
   if (mode.greaterThan(LockMode.READ))
   {
      if (mode == LockMode.WRITE || mode.greaterThan(LockMode.WRITE))
      {
         return tableName + " with (xlock)";
      }
      return tableName + " with (updlock)";
   }
   return tableName;
}


This seems to work ok in ianywhere, but I don't have access to sybase ASE, so I can't test there.

Should this be patched in the dialect in core?

And if so, should this be specific to ianywhere or general to sybase dialects?

Rob


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