`
01jiangwei01
  • 浏览: 542713 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

hibernate 乐观锁 测试

 
阅读更多

准备环境:

    表:demo_lock

CREATE TABLE `demo_lock` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`aversion` int(12) NOT NULL DEFAULT '0',
`avalue` int(12) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of demo_lock
-- ----------------------------
INSERT INTO `demo_lock` VALUES ('1', '0', '0');

 映射类:

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;

import org.hibernate.annotations.GenericGenerator;
/**
 * hibernate 乐观锁测试
 *
 */
@Entity
@Table(name = "demo_lock")
public class DemoLock implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8908901013537360047L;
	
	
	@GenericGenerator(name = "generator", strategy = "increment")
	@GeneratedValue(generator = "generator")
	@Id
	@Column(name = "id", unique = true, nullable = false) 
	private Integer id;
	
	/**
	 * 版本号
	 */
	@Version  
	@Column(name = "aversion" ) 
	private int aversion;
	
	/**
	 * 
	 */
	@Column(name = "avalue" ) 
	private int avalue;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public int getAversion() {
		return aversion;
	}

	public void setAversion(int aversion) {
		this.aversion = aversion;
	}

	public int getAvalue() {
		return avalue;
	}

	public void setAvalue(int avalue) {
		this.avalue = avalue;
	}
}

 DAO:

@Repository
@Scope("prototype")
public class DemoLockDaoImpl extends BaseDAOImpl implements DemoLockDao {

}

 Service:

import java.sql.SQLException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.gxkj.web.jiancai.daos.DemoLockDao;
import com.gxkj.web.jiancai.entitys.DemoLock;
import com.gxkj.web.jiancai.services.DemoLockService;
@Service
@Scope("prototype")
public class DemoLockServiceImpl implements DemoLockService {

	@Autowired
	private DemoLockDao demoLockDao; 
	
	public DemoLock getDemoLockById(int id) throws SQLException {
		return (DemoLock) demoLockDao.selectById(id, DemoLock.class);
	}

	public void updateDemoLock(DemoLock entity) throws SQLException {
		demoLockDao.update(entity);
	}
}

 注意事项:修改时version是必填参数。

分享到:
评论
2 楼 01jiangwei01 2015-08-22  
测试方法1:测试50个线程,同时并发访问。
目标:只有一个通过,其他报错。
注意事项:此处service和dao的scope是prototype的已经去掉。模拟高并发落点是一台服务器。
@Service
public class DemoLockServiceImpl implements DemoLockService {
@Repository
public class DemoLockDaoImpl extends BaseDAOImpl implements DemoLockDao
测试结果是:通过。
测试代码如下:
引用

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import com.gxkj.web.BaseSpringTest;
import com.gxkj.web.jiancai.entitys.DemoLock;
import com.gxkj.web.jiancai.services.DemoLockService;
/**
* 多线程测试乐观锁
*
*/
public class DemoLockServiceTest extends BaseSpringTest {

@Autowired
private DemoLockService demoLockService1;

@Test
public void testUpdateDemoLock() {
int current_version = 10;
int end_post = 3;
int threadCount = 50;

ExecutorService exe = Executors.newFixedThreadPool(threadCount);
CountDownLatch begin = new CountDownLatch(1);
CountDownLatch endGun = new CountDownLatch(threadCount);
 
for(int i=0;i<threadCount;i++){
//DemoLockService service = this.getBean(DemoLockService.class);
MyThread myThread = new MyThread(demoLockService1,i*10+end_post,current_version,begin,endGun);
Thread thread = new Thread(myThread);
exe.execute(thread);  
}
//开始
begin.countDown();
try{ 
             /**
              * 等待,直到最后一个队员完成比赛。
              */ 
             endGun.await();            
         }catch (InterruptedException e) { 
             e.printStackTrace(); 
         }finally{ 
             System.out.println("结束!");
             exe.shutdown();
         } 

}

}
class MyThread implements Runnable {
DemoLockService demoLockService;
int value = 0;
int version = 0;
/**
     * 比赛抢
     */ 
     private CountDownLatch begin;
     private CountDownLatch end;

public MyThread(DemoLockService demoLockService,int value,int version,CountDownLatch begin
,CountDownLatch end) {
super();
this.demoLockService = demoLockService;
this.value = value;
this.version = version;
this.begin = begin;
this.end = end;
}

@Override
public void run() {
try {
begin.await();
} catch (InterruptedException e1) {
e1.printStackTrace();
}  
DemoLock lock = new DemoLock();
lock.setId(1);
lock.setAversion(version);
lock.setAvalue(value);
try {
demoLockService.updateDemoLock(lock);
} catch (Exception e) {
if ( e instanceof org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException){
System.out.println("e1该数据已经被修改了-"+(value/10));
}else if (e instanceof org.hibernate.StaleObjectStateException){
System.out.println("e2该数据已经被修改了-"+(value/10));
}
e.printStackTrace();
}
end.countDown();    //使end状态减1,最终减至0 

}

}
1 楼 01jiangwei01 2015-08-22  
测试方法1:测试50个线程,同时并发访问。
目标:只有一个通过,其他报错。
注意事项:此处service和dao的scope是prototype的。模拟落点是多台服务器。
测试代码如下:
public class DemoLockServiceTest extends BaseSpringTest {

	@Autowired
	private DemoLockService demoLockService1;
	
	@Test
	public void testUpdateDemoLock() {
		int current_version = 8;
		int threadCount = 50;
		
		ExecutorService exe = Executors.newFixedThreadPool(threadCount);
		CountDownLatch begin = new CountDownLatch(1);
		CountDownLatch endGun = new CountDownLatch(threadCount);
		  
		 for(int i=0;i<threadCount;i++){
			 DemoLockService service = this.getBean(DemoLockService.class);
			 MyThread myThread = new MyThread(service,i*10+1,current_version,begin,endGun);
			 Thread thread = new Thread(myThread); 
			 exe.execute(thread);   
		 }
		  
		
		//开始
		begin.countDown(); 
		try{  
             /** 
              * 等待,直到最后一个队员完成比赛。 
              */  
             endGun.await();             
         }catch (InterruptedException e) {  
             e.printStackTrace();  
         }finally{  
             System.out.println("结束!"); 
             exe.shutdown(); 
         }  
		
	}
	
}
class MyThread implements Runnable {
	DemoLockService demoLockService;
	int value = 0;
	int version = 0;
	/** 
     * 比赛抢 
     */  
     private CountDownLatch begin; 
     private CountDownLatch end; 
	
	public MyThread(DemoLockService demoLockService,int value,int version,CountDownLatch begin
			,CountDownLatch end) {
		super();
		this.demoLockService = demoLockService;
		this.value = value;
		this.version = version;
		this.begin = begin; 
		this.end = end;
	}

	@Override
	public void run() {
		 try {
			begin.await();
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}   
		DemoLock lock = new DemoLock();
		lock.setId(1);
		lock.setAversion(version);
		lock.setAvalue(value);
		try {
			demoLockService.updateDemoLock(lock);
		} catch (Exception e) {
			if ( e instanceof org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException){
				System.out.println("该数据已经被修改了-"+(value/10));
			}
			e.printStackTrace();
		}
		end.countDown();    //使end状态减1,最终减至0  
		
	} 
	
}


测试结论是:只有一个通过

相关推荐

    Hibernate悲观锁和乐观锁的实现

    在进行Hibernate的测试时,可以创建一个名为`hibernate_test`的项目,编写对应的实体类、映射文件以及测试用例,模拟并发场景,来深入理解并对比悲观锁和乐观锁的差异和效果。 总之,理解并合理运用悲观锁和乐观锁...

    乐观锁version-练习

    7. **实战演练**:设计并执行一系列测试用例,包括正常更新、并发冲突等,以加深对乐观锁工作原理的理解。 通过这个练习,你不仅可以掌握Hibernate中的乐观锁机制,还能提升对并发控制和数据一致性的理论知识,为...

    Hibernate实现悲观锁和乐观锁代码介绍

    Hibernate 实现悲观锁和乐观锁代码介绍 Hibernate 是一个基于 Java 的持久层框架,它提供了多种锁机制来实现事务的隔离性和一致性。在本文中,我们将详细介绍 Hibernate 实现悲观锁和乐观锁的代码实现,并讨论 ...

    hibernate的三锁

    该资源主要是分析:乐观锁解决事务并发.乐观锁校验测试, 基于hiber管理的悲观锁实现

    hibernate:一对多,多对多,一对一,乐观锁,二级缓存

    Hibernate通过版本号或时间戳实现乐观锁,即在实体类中添加一个版本字段,并在更新时检查版本是否一致。如果一致则更新,不一致则抛出异常。 5. **一级缓存(First Level Cache)**: Hibernate的一级缓存是...

    hibernate锁实验,以及解决方案

    在Hibernate中,乐观锁可以通过`@Version`注解实现。 2. **行级锁与表级锁** - 行级锁:只锁定操作的特定行,允许其他事务操作表中未被锁定的行,提高并发性能。Hibernate支持行级锁。 - 表级锁:锁定整个表,...

    Hibernate项目开发宝典源码(完整版)

    8. **order**:订单系统,可能包含订单创建、支付、取消等业务逻辑,这可能会用到Hibernate的乐观锁、悲观锁机制,以及复杂的查询和更新操作。 通过对这些文件夹的分析,我们可以深入学习以下知识点: - Hibernate...

    hibernate中文参考文档

    - **乐观锁与悲观锁**: 提供了两种不同级别的并发控制机制,以应对多用户环境下的数据冲突问题。 #### 八、错误处理与调试 - **异常处理**: Hibernate提供了多种异常类型,用于指示不同的错误情况,如`...

    Hibernate关键知识点大全

    - 悲观锁和乐观锁是并发控制的两种方式,悲观锁假设冲突频繁,乐观锁则在数据修改时检查冲突。 13. **缓存机制** - Hibernate的一级缓存是Session级别的,二级缓存是SessionFactory级别的,它们能提升查询效率。...

    HIBERNATE doc_document_官方文档_4.3.6_final_2014_8

    - **对象关系映射基础**: 阐述了如何声明映射,包括实体、标识符、乐观锁等。 - **继承的实现、equals()和hashCode()方法的实现、动态模型、Tuplizers、实体名称解析器**: 这些是更高级的ORM概念,说明了如何在...

    Hibernate源码

    9. **实体的版本控制**:学习乐观锁和悲观锁在Hibernate中的实现。 10. **SessionFactory的创建**:分析Configuration类如何配置和生成SessionFactory,以及SessionFactory的生命周期。 深入学习这些知识点,有助于...

    一种基于hebernate乐观锁的信息系统开发模型 (2012年)

    标题中提到的“基于Hibernate乐观锁的信息系统开发模型”是一个工程技术领域的知识点,主要是关于信息系统开发方面的实践。Hibernate是一种流行的Java对象关系映射(ORM)框架,它用于将Java对象映射到数据库的表...

    Hibernate In Action

    书中会阐述Hibernate的事务策略,包括JTA和JDBC事务,以及如何处理并发问题,如乐观锁和悲观锁的实现。 除了基本功能外,本书还将涉及更高级的主题,如性能优化、第二级缓存的使用、HQL(Hibernate查询语言)和SQL...

    hibernate 参考手册

    1. **映射定义**:介绍了Hibernate映射文件的结构和各个部分的作用,比如实体、属性、标识符、乐观锁属性等。 2. **自然ID和组件映射**:讲解了如何使用自然ID作为对象的唯一标识,以及如何映射嵌入式组件。 3. **...

    Spring整合HIbernate

    7. **版本控制**:利用Hibernate的乐观锁或悲观锁机制,保证数据一致性。 通过以上步骤和实践,我们可以有效地整合Spring和Hibernate,构建出高效且易于维护的Java应用。在实际开发中,还需要根据项目需求灵活调整...

    Hibernate开发指南

    - **锁**: 涵盖了悲观锁和乐观锁的概念及实现。 - **Hibernate分页**: 解释了如何在Hibernate中实现分页功能。 - **Cache管理**: 探讨了缓存策略和使用技巧。 - **Session管理**: 分析了Session的生命周期管理。...

    hibernate面试题

    根据提供的信息,我们可以总结出以下关于Hibernate的知识点: ...- **乐观锁**:假设冲突较少,仅在提交时检查是否有冲突。 - **悲观锁**:假设冲突较多,锁定资源直到操作完成。 正确答案为:**B) 乐观锁**。

    hibernate-extensions-2.1.3

    4. **时间戳和版本管理**:提供自动维护乐观锁的机制,以处理并发控制,确保数据一致性。 5. **查询缓存**:增强查询性能,通过缓存查询结果来避免重复的数据库访问。 6. **事件监听器**:通过实现自定义的事件...

Global site tag (gtag.js) - Google Analytics