Hibernate乐观锁实现方式

hibernate乐观锁

,Student.java

 

package com.fgh.hibernate; import java.sql.Timestamp; public class Student { private String id; private String name; private int age; private String cardId; // private Timestamp lastDate; private int version; public int getVersion() { return version; } public void setVersion(int version) { this.version = version; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getCardId() { return cardId; } public void setCardId(String cardId) { this.cardId = cardId; } // public Timestamp getLastDate() { // return lastDate; // } // // public void setLastDate(Timestamp lastDate) { // this.lastDate = lastDate; // } }
Student.hbm.xml

 

 

<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.fgh.hibernate.Student" table="student_optimistic"> <id name="id" column="id" type="string"> <generator class="uuid"></generator> </id> <!-- 这个位置要放在property之前 timestamp和version本质上是一样的 --> <!-- <timestamp name="timestamp" column="lastDate"></timestamp> --> <version name="version" column="version" type="integer"></version> <property name="name" column="name" type="string"></property> <property name="cardId" column="cardId" type="string"></property> <property name="age" column="age" type="integer"></property> </class> </hibernate-mapping>
测试类HibernateTest.java

 

 

package com.fgh.hibernate; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; public class HibernateTest { private static SessionFactory sessionFactory; static { try { sessionFactory = new Configuration().configure() .buildSessionFactory(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { // 生成两个session 模拟双线程并发 Session session1 = sessionFactory.openSession(); Session session2 = sessionFactory.openSession(); //Transaction tx = null; Transaction tx1 = null; Transaction tx2 = null; try { /**保存操作 tx = session.beginTransaction(); Student student = new Student(); student.setAge(20); student.setCardId("123"); student.setName("zhangsan"); session.save(student); tx.commit(); */ // 使用HQL查询 :name叫命名参数 調用setString方法为参数设值 // 然后调用uniqueResult方法返回唯一的对象 Student student1 = (Student) session1.createQuery( "from Student s where s.name=:name").setString("name", "zhangsan").uniqueResult(); Student student2 = (Student) session2.createQuery( "from Student s where s.name=:name").setString("name", "zhangsan").uniqueResult(); System.out.println(student1.getVersion()); System.out.println(student2.getVersion()); // 线程1 修改了name属性 然后提交事务 单独执行 线程1 // 打印出student2的version为0 因为线程2事务还没有提交 tx1 = session1.beginTransaction(); student1.setName("lisi"); tx1.commit(); System.out.println(student1.getVersion()); System.out.println(student2.getVersion()); // 线程2 同样修改了name属性 但是在此之前 已经对name属性做了修改 // 查询的时候name已更新为lisi 所以该处会抛异常StaleObjectStateException //student1 version=1 student2 version=0 tx2 = session2.beginTransaction(); student2.setName("wangwu"); tx2.commit(); } catch (Exception e) { e.printStackTrace(); if (null != tx1) { tx1.rollback(); } else if (null != tx2) { tx2.rollback(); } } finally { session1.close(); session2.close(); } } }

整体执行结果:

Hibernate: select student0_.id as id0_, student0_.version as version0_, student0_.name as name0_, student0_.cardId as cardId0_, student0_.age as age0_ from student_optimistic student0_ where student0_.name=?
Hibernate: select student0_.id as id0_, student0_.version as version0_, student0_.name as name0_, student0_.cardId as cardId0_, student0_.age as age0_ from student_optimistic student0_ where student0_.name=?
0
0
Hibernate: update student_optimistic set version=?, name=?, cardId=?, age=? where id=? and version=?
1
0
Hibernate: update student_optimistic set version=?, name=?, cardId=?, age=? where id=? and version=?
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.fgh.hibernate.Student#8a8ae4d934d2705b0134d2705cfb0001]
at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1765)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2407)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2307)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2607)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.fgh.hibernate.HibernateTest.main(HibernateTest.java:56)
Exception in thread "main" org.hibernate.TransactionException: Transaction not successfully started
at org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:149)
at com.fgh.hibernate.HibernateTest.main(HibernateTest.java:63)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值