`

Hibernate悲观锁与乐观锁及事务管理机制

阅读更多

引用:

悲观锁与乐观锁:

http://www.iteye.com/topic/179267

http://hi.baidu.com/ahuzl/blog/item/1340fe8307dc16b56d81194b.html

事务管理机制:

http://www.router.net.cn/Article/26494.html

http://www.iteye.com/topic/280746

 

悲观锁示例:

POJO 为User类

在示例中从数据库load出来,分别用两个测试方法来,在第一个方法里面设置断点,会发现直到第一个方法执行完,第二个方法才进行更新。

说明锁定的情况下其它session不能更新。

package com.bjsxt.hibernate;

import junit.framework.TestCase;

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

public class PessimisticLockingTest extends TestCase {

	public void testUpdate1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			User user = (User)session.load(User.class, "402880f6286c790b01286c7911eb0001", LockMode.UPGRADE);
			System.out.println("name=" + user.getName());
			System.out.println("password=" + user.getPassword());
			user.setPassword("a");
			session.update(user);
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}		
	}
	
	public void testUpdate2() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			User user = (User)session.load(User.class, "402880f6286c790b01286c7911eb0001", LockMode.UPGRADE);
			System.out.println("name=" + user.getName());
			System.out.println("password=" + user.getPassword());
			user.setPassword("b");
			session.update(user);
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}		
	}	
	
}

 

 

乐观锁:

在User类里面增加属性version

package com.bjsxt.hibernate;

import java.util.Date;

public class User {
	
	private String id;
	
	private String name;
	
	private String password;
	
	private Date createTime;
	
	private Date expireTime;
	
	//采用乐观锁,进行并发控制
	private int version;

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public Date getExpireTime() {
		return expireTime;
	}

	public void setExpireTime(Date expireTime) {
		this.expireTime = expireTime;
	}

	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 String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public int getVersion() {
		return version;
	}

	public void setVersion(int version) {
		this.version = version;
	}
	
}

 

配置文件:

<?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.bjsxt.hibernate.User" optimistic-lock="version">
		<id name="id">
			<generator class="uuid"/>
		</id>
		<version name="version"/>
		<property name="name"/>
		<property name="password"/>
		<property name="createTime"/>
		<property name="expireTime"/>
	</class>
</hibernate-mapping>	

 

 

一样采用两个测试方法进行测试:

package com.bjsxt.hibernate;

import java.util.Date;

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

import junit.framework.TestCase;

public class OptimisticLockingTest extends TestCase {

	public void testUpdate1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			User user = (User)session.load(User.class, "402880f6286c93c101286c93c7130001");
			System.out.println("name=" + user.getName());
			System.out.println("password=" + user.getPassword());
			user.setPassword("a");
			session.update(user);
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}		
	}
	
	public void testUpdate2() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			User user = (User)session.load(User.class, "402880f6286c93c101286c93c7130001");
			System.out.println("name=" + user.getName());
			System.out.println("password=" + user.getPassword());
			System.out.println("version=" + user.getVersion());
			user.setPassword("b");
			session.update(user);
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}		
	}	
}

 

可在第一个方法中设置断点,debug,而第二个方法run。看看执行的情况。

乐观锁User的表

+------------+--------------+------+-----+---------+-------+
| Field      | Type         | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| id         | varchar(255) | NO   | PRI | NULL    |       |
| version    | int(11)      | NO   |     | NULL    |       |
| name       | varchar(255) | YES  |     | NULL    |       |
| password   | varchar(255) | YES  |     | NULL    |       |
| createTime | datetime     | YES  |     | NULL    |       |
| expireTime | datetime     | YES  |     | NULL    |       |
+------------+--------------+------+-----+---------+-------+

 

虽然加了version字段,但是不需要设置该属性值,如下:

package com.bjsxt.hibernate;

import java.util.Date;

import org.hibernate.Session;

public class InitData {

	public static void main(String[] args) {
			Session session = null;
			User user = new User();
			try {
				session = HibernateUtils.getSession();
				session.beginTransaction();
				user.setName("张三");
				user.setPassword("123");
				user.setCreateTime(new Date());
				user.setExpireTime(new Date());
				session.save(user);
				session.getTransaction().commit();
			}catch(Exception e) {
				e.printStackTrace();
				session.getTransaction().rollback();
			}finally {
				HibernateUtils.closeSession(session);
			}
	}
}

 

 

我在测试方法一中的System.out.println("name=" + user.getName());处设置断点,然后执行debug这个方法。

执行到断点处,我们发现从数据库查询出来的version=0,这时再执行测试方法二,会发现测试方法二立刻执行,并把version变成为1,测试方法二执行完,我们再按F6下一步时,测试方法一执行到commit的时候会抛出异常:

这是因为乐观锁发现自身的version<=数据库中的version的时候更新不了。。

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.bjsxt.hibernate.User#402880f6286c93c101286c93c7130001]

 

分享到:
评论

相关推荐

    Hibernate悲观锁与乐观锁

    《Hibernate 悲观锁与乐观锁详解》 在多用户并发访问的环境中,数据库管理系统必须具备有效的数据访问控制机制,以确保数据的一致性和完整性。Hibernate,作为一款流行的Java持久化框架,提供了两种主要的锁定策略...

    Hibernate悲观锁与乐观锁案例

    在Java的持久化框架Hibernate中,悲观锁和乐观锁是两种重要的并发控制策略,它们用于管理数据库中的数据在多线程环境下的访问安全。本文将深入探讨这两种锁机制的原理、应用场景及其区别。 首先,我们来理解悲观锁...

    hibernate乐观锁和悲观锁学习

    本文主要讨论的是Hibernate框架中两种锁机制的使用:乐观锁和悲观锁。 首先,让我们深入理解悲观锁(Pessimistic Locking)。悲观锁正如其名字所示,假设并发环境中数据会被频繁修改,所以在整个数据处理过程中,它...

    hibernate事务管理机制.doc

    【hibernate事务管理机制】是指在使用Hibernate框架进行数据库操作时,如何管理和协调事务的一系列规则和策略。事务管理是确保数据一致性、完整性和并发控制的重要机制。 **悲观锁**是预防性的锁定策略,它假设并发...

    Hibernate 乐观和悲观锁

    在多线程环境下,为了保证数据的一致性和完整性,数据库管理系统提供了多种锁定机制,其中乐观锁和悲观锁是两种常见的实现方式。 1. **悲观锁**:悲观锁假设数据在操作过程中可能会被其他并发事务修改,因此在读取...

    Hibernate性能(缓存 延迟加载 事务 悲观 乐观锁).ppt

    缓存、延迟加载、事务管理和锁定策略是提升Hibernate性能的四大关键要素。 **1. Hibernate缓存** 缓存机制是提高ORM框架性能的核心,它减少了对数据库的直接访问,从而提升了数据读取速度。Hibernate提供了三级缓存...

    Hibernate中,利用版本管理机制来控制事务并发

    2. 事务隔离级别:Hibernate的版本管理机制与数据库的事务隔离级别相结合,可以实现不同级别的并发控制。例如,在可重复读(Repeatable Read)隔离级别下,虽然能防止脏读,但可能会出现幻读,此时版本管理机制可以...

    hibernate5--2.数据持久化及事务

    本章节我们将深入探讨Hibernate 5在数据持久化和事务管理方面的特性与用法。 **1. 数据持久化** 数据持久化是通过Hibernate的核心接口Session来实现的。Session提供了对数据库的 CRUD(创建、读取、更新、删除)...

    Hibernate教程26_事务并发处理

    本教程主要聚焦于Hibernate中的事务并发处理,包括悲观锁和乐观锁两种策略,这对于我们理解如何在高并发环境中确保数据的一致性和完整性至关重要。 首先,事务是数据库操作的基本单元,它确保一组操作要么全部成功...

    Hibernate4实战 之第五部分:Hibernate的事务和并发

    #### 二、Hibernate事务管理机制 Hibernate 本身不实现事务逻辑,而是依赖于底层的数据源(JDBC 或 JTA)来实现事务管理。这意味着,当你使用 Hibernate 进行数据操作时,所涉及的事务要么基于 JDBC 的事务管理,要么...

    乐观锁version-练习

    2. **Hibernate的乐观锁机制**:了解Hibernate如何通过`version`字段实现乐观锁,包括`@Version`注解的使用、对象状态管理及冲突检测。 3. **乐观锁与悲观锁的区别**:对比两种锁的优缺点,例如悲观锁的资源消耗大...

    hibernate 对事务并发处理

    悲观锁采用数据库内部锁机制,在一个事务操作数据时,为数据加锁,另一个事务无法操作。 例如,在 Hibernate 中使用悲观锁: ```java Customer customer = (Customer) session.load(Customer.class, 1, LockMode....

    day36 10-Hibernate中的事务:解决丢失更新

    标题中的“day36 10-Hibernate中的事务:解决丢失更新”指的是在...通过理解并熟练运用Hibernate提供的事务控制机制、乐观锁和悲观锁等工具,开发者可以有效地避免丢失更新和其他并发问题,确保应用程序的数据完整性。

    hibernate事务管理

    在Java的持久化框架中,Hibernate是一个非常重要的工具,它...理解并熟练运用这些事务管理机制,能帮助开发者编写出更加健壮和可靠的Java应用。在实际开发中,应根据项目需求和性能考虑选择合适的事务管理模式和策略。

    Hibernate part 14:查询及数据库并发事务

    **描述:**描述为空,但我们可以推测博客内容可能包含实际示例、最佳实践以及对Hibernate查询API和事务管理机制的详细解释。 **标签:“源码”和“工具”** "源码"标签表明博客可能包含了与Hibernate源代码相关的...

    hibernate锁实验,以及解决方案

    1. **悲观锁与乐观锁** - 悲观锁:在读取数据时就假设会发生并发冲突,因此在读取时会立即加锁,防止其他事务修改数据。在Hibernate中,悲观锁主要通过`LockMode.UPGRADE`实现,即使用`SELECT ... FOR UPDATE`语句...

    hibernate的事务核并发

    同时,Hibernate还支持乐观锁和悲观锁机制,通过版本字段或锁定表行的方式,防止并发修改冲突。 ### 使用ThreadLocal和getCurrentSession() 在多线程环境中,如Web应用或EJB容器,为了保证`Session`的线程安全和...

Global site tag (gtag.js) - Google Analytics