论坛首页 Java企业应用论坛

请教一个用ThreadLocal管理session的问题

浏览 9582 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-04-19  
maoxiaolu2000 写道
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;

public class NetshopSessionFactory {	

    private static String CONFIG_FILE_LOCATION = "/hibernate-netshop.cfg.xml";
	private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    private  static Configuration configuration = new Configuration();
    private static org.hibernate.SessionFactory sessionFactory;
    private static String configFile = CONFIG_FILE_LOCATION;

    private NetshopSessionFactory() {
    }
	
	/**
     * Returns the ThreadLocal Session instance.  Lazy initialize
     * the <code>SessionFactory</code> if needed.
     *
     *  @return Session
     *  @throws HibernateException
     */
    public static Session getSession() throws HibernateException {
        Session session = (Session) threadLocal.get();
        
		if (session == null || !session.isOpen()) {
			if (sessionFactory == null) {
				rebuildSessionFactory();
			}
			session = (sessionFactory != null) ? sessionFactory.openSession()
					: null;
			
			threadLocal.set(session);
		}
		
		
        return session;
    }
    
    /**
     * Returns the ThreadLocal Session instance.  Lazy initialize
     * the <code>SessionFactory</code> if needed.
     *
     *  @return Session
     *  @throws HibernateException
     */
    public static Session getNewSession() throws HibernateException {
        return sessionFactory.openSession();
    }

	/**
     *  Rebuild hibernate session factory
     *
     */
	public static void rebuildSessionFactory() {
		try {
			configuration.configure(configFile);
			sessionFactory = configuration.buildSessionFactory();
		} catch (Exception e) {
			System.err
					.println("%%%% Error Creating SessionFactory %%%%");
			e.printStackTrace();
		}
	}

	/**
     *  Close the single hibernate session instance.
     *
     *  @throws HibernateException
     */
    public static void closeSession() throws HibernateException {
        Session session = (Session) threadLocal.get();
        threadLocal.set(null);

        if (session != null) {
            session.close();
        }
    }

	/**
     *  return session factory
     *
     */
	public static org.hibernate.SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	/**
     *  return session factory
     *
     *	session factory will be rebuilded in the next call
     */
	public static void setConfigFile(String configFile) {
		NetshopSessionFactory.configFile = configFile;
		sessionFactory = null;
	}

	/**
     *  return hibernate configuration
     *
     */
	public static Configuration getConfiguration() {
		return configuration;
	}


}




下面的操作时调用的方法


	public static void saveOrUpdateItem(Item item){
		Session session = NetshopSessionFactory.getSession();
		Transaction tx = session.beginTransaction();
		session.saveOrUpdate(item);
		session.flush();
		tx.commit();
		item = null;		
		session.close();
	}


	public static Item getItemByid(Integer id){		
		Session session = NetshopSessionFactory.getSession();
		session.clear();
		Item item = (Item)session.load("netshop.dolchn.hibernate.Item", id);
		//System.out.println(item.getItname());
		session.close();
		return item;
	}






与楼主的问题一样, 无论session.flush() 还是session.clear(); 脏读数据依然被读出来, 实在不知道这些数据到底缓存在哪里, 二级缓存也已经被关闭了, 我现在怀疑问题出在线程上.


测试的代码贴出来看看
0 请登录后投票
   发表时间:2007-04-20  
写了一个线程类,来模仿一下操作

package test;

import netshop.dolchn.hibernate.Item;
import netshop.dolchn.operation.ItemOP;

public class RunText  extends Thread{
	
	int id;
	Double discount;
	String threadname;
	RunText(int id,Double discount,String threadname){
		this.id = id;
		this.discount = discount;
		this.threadname = threadname;
	}
	
	public void run(){
		for(int i = 0;i < 10; i++){
			if(i==0){
				Item item = ItemOP.getItemByid(id);
				item.setItdiscount(discount);
				ItemOP.saveOrUpdateItem(item);
				System.out.println("线程"+threadname+"设置 discount :"+discount);
			}
			Item item  = ItemOP.getItemByid(id);
			System.out.println("线程"+threadname+"输出:--------------------->"+item.getItdiscount());
			try {
				sleep(50);
			} catch (InterruptedException e) {				
				e.printStackTrace();
			}
			
		}
	}
	
}


package test;

import netshop.dolchn.hibernate.NetshopSessionFactory;
import netshop.dolchn.hibernate.Item;
import netshop.dolchn.operation.ItemOP;



public class TextA  {
	
	public static void main(String[] args){
		
		NetshopSessionFactory.getSession();
		NetshopSessionFactory.closeSession();
		
		Item item = ItemOP.getItemByid(1);
		System.out.println("程序开始:--------------------->"+item.getItdiscount());
		
		RunText ra =new RunText(1,0.9,"A");
		ra.start();
		
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {				
			e.printStackTrace();
		}
		
		RunText rb =new RunText(1,0.8,"B");
		rb.start();
		
		
		
		for(int i=1; i < 30 ; i ++){
			item = ItemOP.getItemByid(1);
			System.out.println(i+":--------------------->"+item.getItdiscount());			
		}
		
		RunText rc =new RunText(1,1.0,"C");
		rc.start();
		
		
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {				
			e.printStackTrace();
		}
		item = ItemOP.getItemByid(1);
		System.out.println("程序束结:--------------------->"+item.getItdiscount());
		
	}
}




输出结果如下:

程序开始:--------------------->1.0
线程A设置 discount :0.9
线程A输出:--------------------->0.9
1:--------------------->0.9
2:--------------------->0.9
3:--------------------->0.9
4:--------------------->0.9
5:--------------------->0.9
6:--------------------->0.9
7:--------------------->0.9
8:--------------------->0.9
9:--------------------->0.9
10:--------------------->0.9
11:--------------------->0.9
12:--------------------->0.9
13:--------------------->0.9
14:--------------------->0.9
15:--------------------->0.9
16:--------------------->0.9
线程B设置 discount :0.8
线程A输出:--------------------->0.8
17:--------------------->0.9
线程B输出:--------------------->0.8
18:--------------------->0.9
19:--------------------->0.9
20:--------------------->0.9
21:--------------------->0.9
22:--------------------->0.9
23:--------------------->0.9
24:--------------------->0.9
25:--------------------->0.9
26:--------------------->0.9
27:--------------------->0.9
28:--------------------->0.9
29:--------------------->0.9
线程A输出:--------------------->0.8
线程B输出:--------------------->0.8
线程C设置 discount :1.0
线程C输出:--------------------->1.0
线程A输出:--------------------->1.0
线程B输出:--------------------->0.8
线程C输出:--------------------->0.8
线程A输出:--------------------->0.8
线程B输出:--------------------->0.8
线程C输出:--------------------->0.8
线程B输出:--------------------->1.0
线程A输出:--------------------->0.8
线程C输出:--------------------->0.8
线程B输出:--------------------->0.8
线程C输出:--------------------->0.8
线程A输出:--------------------->1.0
线程B输出:--------------------->1.0
线程C输出:--------------------->1.0
线程A输出:--------------------->1.0
线程B输出:--------------------->1.0
线程C输出:--------------------->1.0
线程A输出:--------------------->1.0
线程B输出:--------------------->1.0
线程C输出:--------------------->1.0
线程A输出:--------------------->1.0
线程B输出:--------------------->1.0
线程C输出:--------------------->1.0
线程C输出:--------------------->1.0
程序束结:--------------------->1.0


其中有些出输就出现脏读数据
0 请登录后投票
   发表时间:2007-04-20  
今天下午,我又把数据库改成了 sqlserver2000 多次运行结果如下:

程序开始:--------------------->1.0
线程A设置 discount :0.9
线程A输出:--------------------->0.9
线程A输出:--------------------->0.9
1:--------------------->0.9
2:--------------------->0.9
3:--------------------->0.9
4:--------------------->0.9
5:--------------------->0.9
6:--------------------->0.9
7:--------------------->0.9
8:--------------------->0.9
9:--------------------->0.9
10:--------------------->0.9
11:--------------------->0.9
线程B设置 discount :0.8
线程B输出:--------------------->0.8
12:--------------------->0.8
13:--------------------->0.8
线程A输出:--------------------->0.8
14:--------------------->0.8
15:--------------------->0.8
16:--------------------->0.8
17:--------------------->0.8
18:--------------------->0.8
19:--------------------->0.8
20:--------------------->0.8
21:--------------------->0.8
22:--------------------->0.8
23:--------------------->0.8
24:--------------------->0.8
25:--------------------->0.8
26:--------------------->0.8
27:--------------------->0.8
28:--------------------->0.8
29:--------------------->0.8
线程C设置 discount :1.0
线程C输出:--------------------->1.0
线程B输出:--------------------->1.0
线程A输出:--------------------->1.0
线程C输出:--------------------->1.0
线程B输出:--------------------->1.0
线程A输出:--------------------->1.0
线程C输出:--------------------->1.0
线程B输出:--------------------->1.0
线程A输出:--------------------->1.0
线程C输出:--------------------->1.0
线程B输出:--------------------->1.0
线程A输出:--------------------->1.0
线程C输出:--------------------->1.0
线程B输出:--------------------->1.0
线程A输出:--------------------->1.0
线程C输出:--------------------->1.0
线程B输出:--------------------->1.0
线程A输出:--------------------->1.0
线程C输出:--------------------->1.0
线程B输出:--------------------->1.0
线程A输出:--------------------->1.0
线程C输出:--------------------->1.0
线程B输出:--------------------->1.0
线程C输出:--------------------->1.0
线程B输出:--------------------->1.0
线程C输出:--------------------->1.0
程序束结:--------------------->1.0

貌似 在sqlserver 下没有出现脏读问题
这样是不是可以确定问题出在mysql数据库上呢,或是hibernate 对mysql的操作上

mysql> \s
--------------
D:\MySQL\bin\mysql.exe  Ver 14.12 Distrib 5.0.18, for Win32 (ia32)

Connection id:          61
Current database:
Current user:           root@localhost
SSL:                    Not in use
Using delimiter:        ;
Server version:         5.0.18-nt
Protocol version:       10
Connection:             localhost via TCP/IP
Server characterset:    gbk
Db     characterset:    gbk
Client characterset:    gbk
Conn.  characterset:    gbk
TCP port:               3306
Uptime:                 7 hours 32 min 43 sec

Threads: 1  Questions: 4299  Slow queries: 0  Opens: 0  Flush tables: 1  Open tables: 0  Queries per second avg: 0.158
--------------

hibernate 3.1
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics