HQL的悲观锁和乐观锁

悲观锁 就是读写时都加锁

package hibernate_manytomany;

import java.util.Date;

import org.hibernate.LockMode;
import org.hibernate.Session;

import hibernate.belle.Inventory;
import hibernate.belle.FiscalPK;
import hibernate.belle.HibernateUtils;

import junit.framework.TestCase;

public class Extends extends TestCase{


     public void teststore(){


           Session session=null;
           try{ 
                session=HibernateUtils.getSession();
                session.beginTransaction();

                Inventory inv=new Inventory();
                inv.setItemno(1001);
                inv.setName("zara");
                inv.setQuantity(100);

                session.save(inv);
               session.beginTransaction().commit();
           }catch(Exception e)
           {
               e.printStackTrace();
               session.beginTransaction().rollback();

           }finally{

               HibernateUtils.closeSession(session);
           }
         }

     public void testrevise1(){


           Session session=null;
           try{ 
                session=HibernateUtils.getSession();
                session.beginTransaction();

                Inventory inv=(Inventory)session.load(Inventory.class, 1001,LockMode.UPGRADE);

                inv.setQuantity(inv.getQuantity()-20);
                System.out.println("quantity="+inv.getQuantity());

               session.beginTransaction().commit();
           }catch(Exception e)
           {
               e.printStackTrace();
               session.beginTransaction().rollback();

           }finally{

               HibernateUtils.closeSession(session);
           }
         }
     public void testrevise2(){


           Session session=null;
           try{ 
                session=HibernateUtils.getSession();
                session.beginTransaction();

                Inventory inv=(Inventory)session.load(Inventory.class, 1001,LockMode.UPDATE);

                inv.setQuantity(inv.getQuantity()-20);
                System.out.println("2=="+inv.getQuantity());

               session.beginTransaction().commit();
           }catch(Exception e)
           {
               e.printStackTrace();
               session.beginTransaction().rollback();

           }finally{

               HibernateUtils.closeSession(session);
           }
         }
}

当我对1单步调试 不释放的时候 直接run2 会报错

Hibernate: 
    select
        inventory0_.Itemno as Itemno0_0_,
        inventory0_.name as name0_0_,
        inventory0_.quantity as quantity0_0_ 
    from
        t_inv inventory0_ 
    where
        inventory0_.Itemno=? for update

20:37:27,356  WARN JDBCExceptionReporter:77 - SQL Error: 1205, SQLState: 41000
20:37:27,359 ERROR JDBCExceptionReporter:78 - Lock wait timeout exceeded; try restarting transaction
org.hibernate.exception.GenericJDBCException: could not load an entity: [hibernate.belle.Inventory#1001]
    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.loader.Loader.loadEntity(Loader.java:1865)
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3038)
    at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:395)
    at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:375)
    at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:139)
    at org.hibernate.event.def.DefaultLoadEventListener.lockAndLoad(DefaultLoadEventListener.java:297)
    at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:106)
    at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
    at org.hibernate.impl.SessionImpl.load(SessionImpl.java:859)
    at org.hibernate.impl.SessionImpl.load(SessionImpl.java:854)
    at hibernate_manytomany.Extends.testrevise1(Extends.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at junit.framework.TestCase.runTest(TestCase.java:154)
    at junit.framework.TestCase.runBare(TestCase.java:127)
    at junit.framework.TestResult$1.protect(TestResult.java:106)
    at junit.framework.TestResult.runProtected(TestResult.java:124)
    at junit.framework.TestResult.run(TestResult.java:109)
    at junit.framework.TestCase.run(TestCase.java:118)
    at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:131)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3603)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3535)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1989)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2150)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2626)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2119)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2281)
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1778)
    at org.hibernate.loader.Loader.doQuery(Loader.java:662)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
    at org.hibernate.loader.Loader.loadEntity(Loader.java:1851)
    ... 28 more

乐观锁

package hibernate.belle;

import java.util.Date;

public class Inventory {
      private int itemno;
      private int quantity;
      private String name;
      private int version;


    public int getItemno() {
        return itemno;
    }
    public void setItemno(int itemno) {
        this.itemno = itemno;
    }
    public int getQuantity() {
        return quantity;
    }
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getVersion() {
        return version;
    }
    public void setVersion(int version) {
        this.version = version;
    }



}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping >
 <class name="hibernate.belle.Inventory" table="t_inv" optimistic-lock="version">

     <id name="Itemno">

     <generator class="assigned"></generator>

     </id>
     <version name="version"/>
     <property name="name"></property>
     <property name="quantity"></property>


 </class>      
</hibernate-mapping>
package hibernate_manytomany;

import java.util.Date;

import org.hibernate.LockMode;
import org.hibernate.Session;

import hibernate.belle.Inventory;
import hibernate.belle.FiscalPK;
import hibernate.belle.HibernateUtils;

import junit.framework.TestCase;

public class Extends extends TestCase{


     public void teststore(){


           Session session=null;
           try{ 
                session=HibernateUtils.getSession();
                session.beginTransaction();

                Inventory inv=new Inventory();
                inv.setItemno(1001);
                inv.setName("zara");
                inv.setQuantity(100);

                session.save(inv);
               session.beginTransaction().commit();
           }catch(Exception e)
           {
               e.printStackTrace();
               session.beginTransaction().rollback();

           }finally{

               HibernateUtils.closeSession(session);
           }
         }

     public void testrevise1(){


           Session session=null;
           try{ 
                session=HibernateUtils.getSession();
                session.beginTransaction();

                Inventory inv=(Inventory)session.load(Inventory.class, 1001);

                inv.setQuantity(inv.getQuantity()-20);
                System.out.println("revise1"+inv.getVersion());
                System.out.println("quantity="+inv.getQuantity());

               session.beginTransaction().commit();
           }catch(Exception e)
           {
               e.printStackTrace();
               session.beginTransaction().rollback();

           }finally{

               HibernateUtils.closeSession(session);
           }
         }
     public void testrevise2(){


           Session session=null;
           try{ 
                session=HibernateUtils.getSession();
                session.beginTransaction();

                Inventory inv=(Inventory)session.load(Inventory.class, 1001);

                inv.setQuantity(inv.getQuantity()-20);
                System.out.println("revise2"+inv.getVersion());
                System.out.println("quantity="+inv.getQuantity());

               session.beginTransaction().commit();
           }catch(Exception e)
           {
               e.printStackTrace();
               session.beginTransaction().rollback();

           }finally{

               HibernateUtils.closeSession(session);
           }
         }
}

同上 1先占着锁 不释放 然后2直接run 报错 因为 此时数据库里查到的version是1 与1现在所持有的version0 不匹配 报一下错

20:56:22,810 ERROR AbstractFlushingEventListener:301 - Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值