关于linq to sql类线程同步问题

例如,下面一段代码,当两个线程同时访问时会出现各种由于线程不同步而导致的问题,比如什么DataReader已打开未关闭啊,已经添加了重复的键啊等等。

 

 1           /// <summary>
 2           /// 当前数据上下文,非线程安全
 3           /// </summary>
 4           static AouUnionPayDataContext db = new AouUnionPayDataContext(connStr);
 5   
 6           /// <summary>
 7           /// 此处是并发发生错误的方法,当两个线程访问时会出错
 8           /// </summary>
 9           /// <typeparam name="T">查找的实体对象类型</typeparam>
10          /// <param name="predicate">查找的条件,linq to sql语法</param>
11          /// <returns></returns>
12          public T GetSingle(Expression<Func<T, bool>> predicate)
13          {
14              return db.GetTable<T>().SingleOrDefault(predicate);
15          }
非线程安全

 

主要问题在于,多线程情况下同时访问db对象,拿到db对象执行GetTable<T>()方法会出错,相当于都在使用同一个数据库DataReader。这种情况是不允许的。

当项目中很多地方都使用了db此对象,而所有的db都只允许单一线程进行操作时,这时候在代码段头尾加上lock(db){}是不够的。

可以考虑将db封装为线程安全对象,如以下代码:

 1         /// <summary>
 2         /// 当前数据上下文,非线程安全
 3         /// </summary>
 4         static AouUnionPayDataContext db = new AouUnionPayDataContext(connStr);
 5 
 6         /// <summary>
 7         /// 线程安全的数据库访问对象
 8         /// </summary>
 9         protected static AouUnionPayDataContext db_safe
10         {
11             set
12             {
13                 lock(db)
14                 {
15                     db = value;
16                 }
17             }
18             get
19             {
20                 lock(db)
21                 {
22                     return db;
23                 }
24             }
25         }    
26 
27         /// <summary>
28         /// 使用了线程安全对象
29         /// </summary>
30         /// <typeparam name="T">查找的实体对象类型</typeparam>
31         /// <param name="predicate">查找的条件,linq to sql语法</param>
32         /// <returns></returns>
33         public T GetSingle(Expression<Func<T, bool>> predicate)
34         {
35             return db_safe.GetTable<T>().SingleOrDefault(predicate);
36         }
线程安全封装

 

posted @ 2016-07-16 10:36  zhoushiya  阅读(492)  评论(0编辑  收藏  举报