首页 > 代码库 > Hibernate锁
Hibernate锁
悲观锁
从加载对象就开始锁定。修改过程中一直是锁。直到commit()提交后再解锁。
session.load(Info.class,"p003",LockOptions.UPGRADE);
实例:
public class TestPessimisticLock extends TestCase { @Test public void testLock1(){ Session session = null; try { session = HibernateUtil.getSession();//开始锁定,下面的testLock2不能执行 session.beginTransaction(); Info data = session.load(Info.class, "p003", LockOptions.UPGRADE); data.setName("1111111"); session.getTransaction().commit();//执行以后才解锁,这时testLock2才可以执行 } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally{ HibernateUtil.closeSession(); } } @Test public void testLock2(){ Session session = null; try { session = HibernateUtil.getSession(); session.beginTransaction(); Info data = session.load(Info.class, "p003", LockOptions.UPGRADE); data.setName("2222222"); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally{ HibernateUtil.closeSession(); } } }
乐观锁
实际不算锁,只是多线程控制。在提交时间进行冲突检测。把里面的内容与刚开始读取的内容对照一下。有问题就抛异常。
1.在数据库表中加一个字段version
2.在实体类中加一个属性version
public class Info implements java.io.Serializable { private String code; private Nation nation; private String name; private Boolean sex; private Date birthday; private Set families = new HashSet(0); private Set works = new HashSet(0); private int version;//添加一个属性version,并生成getter和setter public int getVersion() { return version; } public void setVersion(int version) { this.version = version; }
3.在映谢文件中配置<version name="version"> 位置 放在<id></id>下面
<hibernate-mapping> <class name="com.itnba.maya.model.Info" table="info" catalog="mydb" optimistic-lock="version"> <cache usage="read-write"/> <id name="code" type="string"> <column name="Code" length="50" /> <generator class="assigned" /> </id> <!-- 配置version,位置放在<id></id>下面 --> <version name="version"></version> <many-to-one name="nation" class="com.itnba.maya.model.Nation" fetch="select"> <column name="Nation" length="50" /> </many-to-one> <property name="name" type="string"> <column name="Name" length="50" /> </property> .... </class> </hibernate-mapping>
其余代码不做改变。
实例:
public class TestOptimisticLock extends TestCase{ @Test public void testLock2(){ Session session = null; try { session = HibernateUtil.getSession(); session.beginTransaction(); Info data = session.load(Info.class, "p002"); data.setName("2222222"); session.getTransaction().commit();//在此时进行冲突检测,version的值与刚开始读取的version值比较。值不同就就抛异常,意为无法操作。 } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally{ HibernateUtil.closeSession(); } } @Test public void testLock1(){ Session session = null; try { session = HibernateUtil.getSession(); session.beginTransaction(); Info data = session.load(Info.class, "p002"); data.setName("1111111"); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally{ HibernateUtil.closeSession(); } } }
假如没有使用hibernate,那么这样来处理并发冲突
Info oldInfo = ... Info newInfo =... //where前面的内容用newInfo的属性,where后面的内容用oldInfo的属性 update info set name=?,sex=?,nation=?,birthday=? where code=? and name=? and sex=? and nation=? and birthday=? executeUpdate(); //返回值为int,如果出现冲突,提示-更新的行数0----表示有并发冲突
Hibernate锁
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。