`
01jiangwei01
  • 浏览: 532671 次
  • 性别: 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  
		
	} 
	
}


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

相关推荐

Global site tag (gtag.js) - Google Analytics