-->
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.  [ 20 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: LockMode problem
PostPosted: Tue Nov 23, 2004 1:55 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
Hello,
I try next scenario with hibernate :

Step 1) user populate rows in session A and close session A

Step 2) use choose row 1 and change

Step 3) user call save and commit work

It work fine except that another user can update row 1 between step 1 and step 2 and his changes aren't saved

Now I want lock row in step 2 and do :

step 1) populate in session A and close session A

step 2) user choose row 1 and when he update row I open new session B and new transaction T and call lock(row,LockMode.UPGRADE_NOWAIT)

another user can't update row 1 now

step 3) User choose save and I call
B.update(row);
T.commit();
B.close();

However, Hibernate doesn't update row.Why ?

I try this scenario in Oracle sqlplus with :

select *
from mytab
where id=1
for update of id,name;

<...
<1 row selected

-- another user can't change row 1

update mytab set name='another name' where id=1;

< 1 row updated

commit;

< commit complete.

regards
Haris Peco


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 1:57 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
I've no idea what you are talking about.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 2:24 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
Christian,
It is simple.
I can't update row after LockMode.UPGRADE in same session, same transaction

select .. FOR UPDATE OF denied update form another transaction, but not from same transaction

regards


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 2:27 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
Quote:
I can't update row after LockMode.UPGRADE in same session, same transaction


you mean after locking with lockmode upgrade or upgrade no wait, changes made to you persistent object can't be persisted?

are you sure about the transaction begin? when is it called?

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 2:42 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
This is code :
LockMode.UPGRADE

lock on change :

try {
openTransaction();
transactionSession.lock(getCurrentBean(),
LockMode.UPGRADE_NOWAIT);
getCurrentBean().setChanged(changed);
} catch (HibernateException e) {
rollback();
fireMessageListener("setchanged.exception");
if (logger.isDebugEnabled())
logger.debug(e.getMessage());
}

private void openTransaction () throws HibernateException {
if (transactionSession == null) {
transactionSession = getSessionFactory().openSession();
transaction = transactionSession.beginTransaction();
}
}

update :

try {
openTransaction();
transactionSession.update(getCurrentBean());
commitTransaction();
} catch (HibernateException e) {
rollback();
fireMessageListener("save.update");
if (logger.isDebugEnabled()) {
logger.debug(e.getMessage());
}
} finally {
refresh();
}

private void commitTransaction() throws HibernateException {
if (transaction != null) {
//transactionSession.flush();
transaction.commit();
transactionSession.close();
}
transactionSession = null;
transaction=null;
}
rollback :

try {
rollbackTransaction();
} catch (HibernateException e) {
fireMessageListener("rollback.exception");
logger.error(e.getMessage());
}
refresh();

private void rollbackTransaction() throws HibernateException {
if (transaction != null) {
transaction.rollback();
transactionSession.close();
}
transactionSession = null;
transaction = null;
}

refresh load rows in another session (without transaction - it is Oracle)

openTransaction,commitTransaction and roolbackTransaction will open only one transaction

regards


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 2:44 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Please repost, use proper indentation and code blocks.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 2:47 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
transactionSession.update(getCurrentBean());


is your instance detached? sounds strange this may be broken, lock also re attach an instance if it is detached so you don't need to call update...

also prefer threadlocal holding for transaction

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 2:52 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
lock
Code:
         try {
                openTransaction();
               
                transactionSession.lock(getCurrentBean(),
                        LockMode.UPGRADE_NOWAIT);
                getCurrentBean().setChanged(changed);
            } catch (HibernateException e) {
                rollback();
                fireMessageListener("setchanged.exception");
                if (logger.isDebugEnabled())
                    logger.debug(e.getMessage());
            }


commit

Code:
         try {
            openTransaction();
            transactionSession.update(getCurrentBean());
            commitTransaction();
        } catch (HibernateException e) {
            rollback();
            fireMessageListener("save.update");
            if (logger.isDebugEnabled()) {
                logger.debug(e.getMessage());
            }
        } finally {
            refresh();
        }


rollback :

Code:
        try {
            rollbackTransaction();
        } catch (HibernateException e) {
            fireMessageListener("rollback.exception");
            logger.error(e.getMessage());
        } finally {
           refresh();
        }


methods :
Code:
private void openTransaction () throws HibernateException {
        if (transactionSession == null) {
            transactionSession = getSessionFactory().openSession();
            transaction = transactionSession.beginTransaction();
        }
    }
   
    private void commitTransaction() throws HibernateException {
        if (transaction != null) {
            //transactionSession.flush();
            transaction.commit();
            transactionSession.close();
        }
        transactionSession = null;
        transaction=null;
    }
    private void rollbackTransaction() throws HibernateException {
        if (transaction != null) {
            transaction.rollback();
            transactionSession.close();
        }
        transactionSession = null;
        transaction = null;
    }


regards


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 2:54 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
I've still no idea what this is about, so I'm giving up.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 3:30 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
Anthony, Christian,

I make test case (one test success and 2 test fail - test name talk
Code:
package org.springframework.richclient.test.hibernate;

import org.springframework.richclient.model.hibernate.AdmSnpeMenus;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.LockMode;
import net.sf.hibernate.Session;
import net.sf.hibernate.Transaction;

/**
* @author snpe
*
*/
public class HibernateUpgradeTests extends BaseHibernateWithouSpringTests {

    private Session session;
    private Session transactionSession;
    private Transaction transaction;
   
    protected void setUp() throws Exception {
        AdmSnpeMenus menu = getMenu();
        menu.setImg("neki.gif");
        openTransaction();
        transactionSession.update(menu);
        commitTransaction();
    }
   
    protected void tearDown() throws Exception {
    }
   
    public HibernateUpgradeTests(String name) {
        super(name);
    }

    public void testLockUpgradeSuccess() throws HibernateException {
        AdmSnpeMenus menu = getMenu();
        assertTrue("id=neki",menu.getId().equals("neki"));
        assertTrue("img = neki.gif",menu.getImg().equals("neki.gif"));
        openTransaction();
        transactionSession.lock(menu,LockMode.UPGRADE_NOWAIT);
        menu.setImg("another.gif");
        transactionSession.update(menu);
        commitTransaction();
        menu = getMenu();
        assertTrue("neki=another.gif",menu.getImg().equals("another.gif"));
    }
   
    public void testLockUpgradeFail1() throws HibernateException {
        AdmSnpeMenus menu = getMenu();
        assertTrue("id=neki",menu.getId().equals("neki"));
        assertTrue("img = neki.gif",menu.getImg().equals("neki.gif"));
        menu.setImg("another.gif");
        openTransaction();
        transactionSession.lock(menu,LockMode.UPGRADE_NOWAIT);
        transactionSession.update(menu);
        commitTransaction();
        menu = getMenu();
        assertTrue("neki=another.gif",menu.getImg().equals("another.gif"));
    }
   
    public void testLockUpgradeFail2() throws HibernateException {
        AdmSnpeMenus menu = getMenu();
        assertTrue("id=neki",menu.getId().equals("neki"));
        assertTrue("img = neki.gif",menu.getImg().equals("neki.gif"));
        openTransaction();
        menu.setImg("another.gif");
        transactionSession.lock(menu,LockMode.UPGRADE_NOWAIT);
        transactionSession.update(menu);
        commitTransaction();
        menu = getMenu();
        assertTrue("neki=another.gif",menu.getImg().equals("another.gif"));
    }
   
    private AdmSnpeMenus getMenu() throws HibernateException {
        session = getSessionFactory().openSession();
        String query = "from " + AdmSnpeMenus.class.getName()
        + " as menu where menu.id = 'neki' ";
        AdmSnpeMenus menu = (AdmSnpeMenus) session.find(query).get(0);
        session.close();
        return menu;
    }
   
    private void openTransaction () throws HibernateException {
        if (transactionSession == null) {
            transactionSession = getSessionFactory().openSession();
            transaction = transactionSession.beginTransaction();
        }
    }
   
    private void commitTransaction() throws HibernateException {
        if (transaction != null) {
            //transactionSession.flush();
            transaction.commit();
            transactionSession.close();
        }
        transactionSession = null;
        transaction=null;
    }
    private void rollbackTransaction() throws HibernateException {
        if (transaction != null) {
            transaction.rollback();
            transactionSession.close();
        }
        transactionSession = null;
        transaction = null;
    }

}



regards


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 3:35 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
this is the expected behaviour

Code:
    public void testLockUpgradeSuccess() throws HibernateException {
        AdmSnpeMenus menu = getMenu();
        assertTrue("id=neki",menu.getId().equals("neki"));
        assertTrue("img = neki.gif",menu.getImg().equals("neki.gif"));
        openTransaction();
        transactionSession.lock(menu,LockMode.UPGRADE_NOWAIT);
        menu.setImg("another.gif");
// update isn't necessary here       
//transactionSession.update(menu);
        commitTransaction();
        menu = getMenu();
        assertTrue("neki=another.gif",menu.getImg().equals("another.gif"));
    }
   
    public void testLockUpgradeFail1() throws HibernateException {
        AdmSnpeMenus menu = getMenu();
        assertTrue("id=neki",menu.getId().equals("neki"));
        assertTrue("img = neki.gif",menu.getImg().equals("neki.gif"));
        menu.setImg("another.gif");
        openTransaction();
// here you're saying to re attach with lock and detached instance you it //hasn't been modified during detachement       
transactionSession.lock(menu,LockMode.UPGRADE_NOWAIT);

// here you're telling to reattach a detached modified instance, this one isn't detached anymore because of the previous session.lock....
        transactionSession.update(menu);
        commitTransaction();
        menu = getMenu();
        assertTrue("neki=another.gif",menu.getImg().equals("another.gif"));
    }


_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Last edited by anthony on Tue Nov 23, 2004 3:39 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 3:38 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
Why ? Why lock have Object parameter ?

regards


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 3:40 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
i've edited my previous reply, read it

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 3:48 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
Anthony,
I make swing application (spring rcp) and this is scenario :

- user populate rows and he haven't any lock
- when user type any character in form I want lock this row with user's changes
- when user call sav button I commit transaction

What is correct use case ?

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 23, 2004 4:36 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
why don't you use versionning?

pessimistic lock is really heavy and in your case, you should have a very long transaction

_________________
Anthony,
Get value thanks to your skills: http://www.redhat.com/certification


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 20 posts ]  Go to page 1, 2  Next

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.