论坛首页 编程语言技术论坛

.net1.1中如何实现类似于Java中ThreadLocal的功能

浏览 5141 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-08-20  
.net1.1中实现事务处理主要有两种方法,一种是使用数据库连接对象的事务处理功能,另一种是使用COM+的事务处理方式。前者适合于在一个方法内完成对数据库的处理,如果一个事务跨越多个方法,就会使得代码复杂度增大和难以控制,容易出错;后者太过于笨重,而且要求使用事务的对象必须从ServicedComponent继承。

由于这两种方法都不是让人很舒服,因此我想自己实现一种方法,利用ThreadLocal的功能来实现,但.net1.1并没有这样的功能,只能自己实现,不知道如下的方法能否实现这一功能:在一个单例的对象里面存储一个线程安全的哈希表,该哈希表以线程为键,数据库连接为值,保证同一段时间内每一个线程都会有一个与其他线程不同的数据库连接。示例代码如下:


                //单例
		private static UserTransaction instance = new UserTransaction();

		private Hashtable connections;
		private Hashtable transactions;

		private UserTransaction()
		{
			connections = Hashtable.Synchronized(new Hashtable());
			transactions = Hashtable.Synchronized(new Hashtable());
		}

		public static UserTransaction Instance
		{
			get { return instance; }
		}

                //获取当前数据库连接
		public OracleConnection GetConnection()
		{
			OracleConnection conn = (OracleConnection) connections[Thread.CurrentThread];
			if (conn == null)
			{
				conn = new OracleConnection(strConn);
				connections.Add(Thread.CurrentThread, conn);
				conn.Open();
			}
			return conn;
		}

                //释放当前数据库连接
		public void ReleaseConnection()
		{
			IDbConnection conn = (OracleConnection) connections[Thread.CurrentThread];
			if (conn != null)
			{
				if (this.GetTransaction() == null)
				{
					Close(conn);
					connections.Remove(Thread.CurrentThread);
				}
			}
		}

                //获取当前数据库事务
		public OracleTransaction GetTransaction()
		{
			OracleTransaction transaction = (OracleTransaction) transactions[Thread.CurrentThread]; 
			return transaction;
		}

                //开启当前事务
		public void StartTransaction()
		{
			IDbConnection conn = (OracleConnection) connections[Thread.CurrentThread];
			if (conn == null)
			{
				conn = new OracleConnection(strConn);
				connections.Add(Thread.CurrentThread, conn);
				conn.Open();
				IDbTransaction transaction = conn.BeginTransaction();
				transactions.Add(Thread.CurrentThread, transaction);
			}
		}

                //提交当前事务
		public void CommitTransaction()
		{
			IDbConnection conn = (OracleConnection) connections[Thread.CurrentThread];
			IDbTransaction transaction = this.GetTransaction();
			transaction.Commit();
			Close(conn);
			connections.Remove(Thread.CurrentThread);
			transactions.Remove(Thread.CurrentThread);
		}

                //回滚当前事务
		public void RollbackTransaction()
		{
			IDbConnection conn = (OracleConnection) connections[Thread.CurrentThread];
			IDbTransaction transaction = this.GetTransaction();
			transaction.Rollback();
			Close(conn);
			connections.Remove(Thread.CurrentThread);
			transactions.Remove(Thread.CurrentThread);
		}



不知道这段代码能否实现类似Java的ThreadLocal的功能?请有经验的人指教一下,谢谢了。
   发表时间:2007-08-20  
简单的方法是使用ThreadStatic attribute

或者直接使用Thread对象的AllocateDataSlot ,AllocateNamedDataSlot

对于事务处理,可以使用spring.net 的事务处理机制

抱歉,没看你的代码

0 请登录后投票
   发表时间:2007-08-20  
C#当然有这样的功能,如楼上所说,而且推荐使用ThreadStatic, 用法如下:
public class A
{
    [ThreadStatic]
    private static UserTransaction instance;
    
    public UserTransaction CurrentTransaction
    {
        get 
        {
            if (instance == null)
            {
                instance = new UserTransaction();
            }
            return instance;
        }
    }
}


用Synchronized Hashtable的话performance估计会受一定影响。因为一个thread来取数据其实不需要lock什么东西的.
0 请登录后投票
   发表时间:2007-08-21  
原来有这样的功能啊,是我孤陋寡闻了。多谢楼上的两位指点。
0 请登录后投票
   发表时间:2007-08-22  
ThreadStatic
不懂你的想法,推荐用sping的Data和Transaction。
0 请登录后投票
论坛首页 编程语言技术版

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