Hibernate 悲观锁 的实现

使用一个线程安全的Session:SessionFactory.getCurrentSession()

 
需要配置Hibernate.cfg.xml 属性current_session_context_class = thread
 
从数据库获取数据时,要加锁session.get(SomeClass.Class,id,LockMode.UPGRADE)
 
试了一晚上,用Mysql做的测试,居然不行...下面的代码仅在Oracle下测试通过
 
实体类
 

public class Book {
 private int bid;
 private String name;
 private boolean borrow = false;
 private String owner;
} //省略无参构造函数和getter/setter    

 
 
borrow布尔类型变量用于标识书是否被借出
 
owner 用于标识当前拥有者
 
测试线程类(测试多线程并发访问情况下悲观锁的效果)
 

public class Student extends Thread {
 private int bookid;
 private String stdname;
 public Student(String name,int bookid){
  this.bookid = bookid;
  this.stdname = name;
 }
 public void run(){
  
  if(this.borrowBook()){
   System.out.println(this.stdname + "借书 成功!!!");
  }else{
   System.out.println(this.stdname + "借书 失败!!!");
  }
 }
 public boolean borrowBook(){
  Session ss = null;
  Transaction ts = null;
  Book book = null;
  try{
   ss = DBFactory.sf.openSession();
   ts = ss.beginTransaction();
   book = (Book) ss.get(Book.class,bookid, LockMode.UPGRADE);
   if(book.isBorrow()){ //书已经借出的情况返回false
    System.out.println("isborrow_false");
    return false;
   }
   book.setBorrow(true);
   book.setOwner(this.stdname);
   ss.save(book);
   ts.commit(); 
   return true;  //借书成功,返回true
  }catch(Exception e){
   ts.rollback();
   e.printStackTrace();
   System.out.println("Exception_false");
   return false; //出错的时候返回false
  }finally{
   ss.close();
  }
 }
}

 
 
Hibernate 配置文件 <property name="current_session_context_class">thread</property>
 
产生Session的工具类
 

public class DBFactory {
 public static SessionFactory sf = null;
 static{
  sf = new Configuration().configure().buildSessionFactory();
 }
 public static Session getSession(){
  return sf.getCurrentSession();   //注意,此处返回的是线程安全的currentSession
 }
}
 

 测试类
 

public class Test {
 
 public static void main(String[] args) {
//  addBook();   //用于构造books表的方法调用
  Student lixun = new Student("Lixun",1);    //开启两个独立线程去借书
  lixun.start();
  Student zhougege = new Student("zhougege",1);
  zhougege.start();
 

  

 }
 
 public static void addBook(){ //用于构造books表的方法
  Book book = new Book();
  book.setName("**Mei");
  Session ss = null;
  Transaction ts = null;
  try{
   ss = DBFactory.sf.openSession();
   ts = ss.beginTransaction();
   ss.save(book);
   ts.commit();
   ss.close();
  }catch(Exception e){
   ts.rollback();
   e.printStackTrace();
  }
 }
}

 

你可能感兴趣的:(多线程,thread,oracle,Hibernate,mysql)