乐观锁配置使用

来源:互联网 发布:手机淘宝怎么引流 编辑:程序博客网 时间:2024/04/28 07:31
乐观锁:乐观的认为我在操作的时候,一定是没有和我一起操作同一个数据的。

原理:在数据库表里面添加一个字段Version。每次修改一次数据的时候,把表里的Version+1,当提交的时候就判断当前的version大不大于数据库里面的version,大于就可以提交,不大于就不能提交并报出异常StaleObjectStateException。

实体Bean:

private Long id;private String userName;private Integer age;private Long version;public UserBean() {super();// TODO Auto-generated constructor stub}public long getVersion() {return version;}public void setVersion(long version) {this.version = version;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "UserBean [id=" + id + ", userName=" + userName + ", age=" + age + ", version=" + version + "]";}

xml配置:

  <hibernate-mapping>    <class name="org.framestudy.hibernate0810.beans.UserBean" table="t_user" catalog="sm">  <id name="id" column="id"  type="java.lang.Long">  <generator class="native" /> <!--根据数据库的主键自动增长-->  <!--identity 自定义,采用数据库的自增长策略,hibernate框架与应用程序不负责ID生产,数据库主键必须是自增长-->  <!--increment 自增长,数据库不能拥有自增长策略,而是由hibernate框架完成ID的自增长生产。极有可能出错 -->  <!--uuid.hex 数据库中id列必须为字符类型,长度不能小于32位,这种生产方式采用计算机IP,MAC,时间戳等  一系列不重复的内容共同组成,然后采用某些特殊算法得到的32位不重复的字符串-->  <!--assigned 数据库与hibernate都不负责ID的生产,ID需要用过应用程序调用SetID()来完成ID的生产-->  <!--foreign 外来的,本表的ID来自于其他表的ID-->  <!--native 框架不提供生产ID,跟着数据库的自增长实现  -->  </id>  <version name="version"  column="version" type="java.lang.Long"></version>//version一定是加在id的后面  <property name="userName" column="user_name" type="java.lang.String"/>  <property name="age" column="age" type="java.lang.Integer"></property>  </class>  </hibernate-mapping>  

  

测试:

Session session =SessionUtils.getSession();Session session2 =SessionUtils.getSession();Transaction tx1 = session.beginTransaction();Transaction tx2 = session2.beginTransaction();UserBean ub = (UserBean) session.get(UserBean.class, 9l);UserBean ub2 = (UserBean) session.get(UserBean.class, 9l);ub2.setUserName("小王");session2.saveOrUpdate(ub2);tx2.commit();ub.setUserName("小李");session.saveOrUpdate(ub);tx1.commit();

 测试结果:

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [org.framestudy.hibernate0810.beans.UserBean#9]at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:2541)at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3285)at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3183)at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3525)at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:159)at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:465)at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:351)at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1258)at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)at org.framestudy.hibernate0810.TestUserServiceImpl.findUserByidupdate(TestUserServiceImpl.java:70)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:483)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:85)at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:86)at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:241)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)at org.junit.runners.ParentRunner.run(ParentRunner.java:363)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)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:678)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

  两次同时访问如果报StaleObjectStateException异常,就证明你的乐观锁成功了。

原创粉丝点击