多session下的事务隔离级别

来源:互联网 发布:房产php源码 编辑:程序博客网 时间:2024/05/21 11:23

//事务的隔离级配置为repeatable read

 

package com.test;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.model.Account;

public class TestHql2 extends Thread{
    public static Session s=HibernateSessionFactory.getSession();
    public static void main(String args[]){
        //s = ;
        test0();
        
    }
    public static void test0(){
        Thread t = new ReadDatabase2();
        t.start();
        
         s = HibernateSessionFactory.getSession();//Session
        Transaction t0 = s.beginTransaction();
        try{
        System.out.println("取款事务:开始事务 ");
        delay(2);
        Account get = (Account)s.load(Account.class, new Integer(1));
        System.out.println("取款事务:查询账户的余额为: "+get.getBalance());
        delay(2);
        get.setBalance(get.getBalance().intValue()-100);//取出100元
        System.out.println("取款事务:准备提交");
        t0.commit();
        System.out.println("取款事务:结束事务");
        delay(10);
        }catch(Exception e){
            System.out.println("取款事务: 出错");
            if(null !=t0)
            t0.rollback();
        }
    //    s.close();
    }
    public static void test2(){
        
    }
    
    public static void delay(int seconds){
        try {
            Thread.currentThread().sleep(1000 * seconds);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
}
class ReadDatabase2 extends Thread {

    @Override
    public void run() {
            Session s = HibernateSessionFactory.getSession();
            Transaction t2=null;
            try {
                Thread.currentThread().sleep(1000 * 1);
                
            System.out.println("存款事务:开始事务");
            t2 = s.beginTransaction();
            
            TestHql2.delay(2);
            
            Account save = (Account)s.load(Account.class, new Integer(1));
            System.out.println("存款事务:查询账户的余额为 "+save.getBalance());
            TestHql2.delay(4);
            
            save.setBalance(save.getBalance()+100);
            System.out.println("存款事务:提交事务");
            t2.commit();
            
            //TestHql2.s.close();
            } catch (Exception e) {
                System.out.println("have an error");
                e.printStackTrace();
                if(null !=t2)
                    t2.rollback();
            }finally {
                
                //TestHql2.s.close();
            }
    }
    

}

 

执行结果为:

 

15:47:31,820  WARN Configurator:126 - No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: jar:file:/D:/jar/all/ehcache-1.1.jar!/ehcache-failsafe.xml
取款事务:开始事务
存款事务:开始事务
Hibernate: select account0_.ID as ID2_0_, account0_.USERNAME as USERNAME2_0_, account0_.BALANCE as BALANCE2_0_ from accounts account0_ where account0_.ID=?
取款事务:查询账户的余额为: 1000
Hibernate: select account0_.ID as ID2_0_, account0_.USERNAME as USERNAME2_0_, account0_.BALANCE as BALANCE2_0_ from accounts account0_ where account0_.ID=?
存款事务:查询账户的余额为 1000
取款事务:准备提交
Hibernate: update accounts set USERNAME=?, BALANCE=? where ID=?
取款事务:结束事务
存款事务:提交事务
Hibernate: update accounts set USERNAME=?, BALANCE=? where ID=?

 

个人看法:

 

执行前mysql表中:admin的balance为1000,执行后balance为1100,出现第二类丢失更新。

当把事务隔离级别定为serializable时,最后就不会产生第二类丢失更新了

 

从结果可以看出在多session下的repeatable read 并没有添加版本控制,不然的换存款事务该报异常才是。

 

原创粉丝点击