• 关于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         }
    线程安全封装
  • 相关阅读:
    Git配置SSH访问GitHub
    vue 관련
    node
    关于CheckBox和EditText在ListView里多布局的处理
    百度地图定位
    java常用简单正则表达式写法
    Android二维码开源项目zxing编译
    Andrew XUtils的session获得和cookieStore使用
    常用易忘知识点
    替换Fragment 报错 The specified child already has a parent. You must call removeView()
  • 原文地址:https://www.cnblogs.com/zhoushiya/p/5675738.html
Copyright © 2020-2023  润新知