乐观锁配置使用

乐观锁:乐观的认为我在操作的时候,一定是没有和我一起操作同一个数据的。

原理:在数据库表里面添加一个字段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;
	}

	@Override
	public 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异常,就证明你的乐观锁成功了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值