线程安全

SqlSugar和.NET ADO的 SqlConnection是一样的,一个线程只能是一个实例,单实例跨线程使用是错误用法


在使用线程是下面的代码是正确用法

for (int i = 0; i < 100; i++)
{
  Thread t = new Thread(new ThreadStart(() =>
  {
      var db = GetInstance();//在不同线程都会new出一个实例
  
  }));
  t.Start();
}



SqlSugar写成变量很容易出现线程问题

改成属性就可以避免,因为一些初学者代码不严谨经常出错,下面会举例说明


正确用法1:属性每次会new新实例

public static SqlSugarClient Instance //注意当前方法的类不能是静态的 public static class这么写是错误的
{
  get{ return new SqlSugarClient(XXX);};
}
 
//用法
var db = 类.Instance;
db.Queryable<T>().ToList();

正确用法2:

public class 类{

  public SqlSugarClient Instance
  {
     get{ return new SqlSugarClient(XXX);};
  }
}
 
//用法
var db = new 类().Instance;
db.Queryable<T>().ToList();



错误写法1

public static SqlSugarClient Instance= new SqlSugarClient (XXX);


错误写法2

//因为这儿是静态的就出错了
public static 类 Instance= new 类();


public class 类{
   public  SqlSugarClient Instance= new SqlSugarClient (XXX);
}

Instance.Db.Sqluery<T>().ToList();//这样SqlSugarClient只会是一个实例所以会出错



//如果这儿不写成静态的
public 类 Instance= new 类(); 

public  class 上层类{
    public static 类  类=new 类(); //这儿是静态的一样会出错

}
//所以不写成属性只要一层是静态的都会出问题

注意:数据库未释放或者datareader已存在都是自已代码问题,我花了大量时间解释给一些初学者,所以这里重点提出来






释放数据库

SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
{ 
    ConnectionString = Config.ConnectionString, //必填
    DbType = DbType.SqlServer,   //必填
    IsAutoCloseConnection = true //默认SystemTable
});



当参数IsAutoCloseConnection 设为true


每次执行操作都会执行 connection.close ,事务内特殊些,会在事务回滚或提交的的时候执行 connection.close


当参数IsAutoCloseConnection 设为false


需要用using(var db=getInstance()) 或者db.Ado.Dispose()或者db.Ado.Close()进行释放


db.dispose和using整个对象都不能使用 close释放掉下次还可以开始



正确的测试是否释放成功

当然了按我上面的代码来写是没有问题的,如果还有怀疑就自已去测试,当然很多人测试方式不对我来这里纠正一下


单线程测试

这种方式是OK的单线程进行测试保证你的对象是否成功释放掉

for (int i = 0; i < 10000; i++)
{
                 
      var db = GetInstance();
      //操作
      db.Queryable<T>().ToList();
}


多线程测试

就要注意上面的的线程安全问题 ,然后还需要注意默认连接池的大小 例如默认是100

最好用并发工具进行测试因为工具是在一秒内进行了100次请求,这100次请求可能是每10毫秒一次,因为有释放机质 400的并发可能一点问题没有,单纯开线程的方式触发点在同一个时间直接超过连接池上限报错。


例如最大连接池是100 ,你的的程序处理时间是10MS,你的并发最多只能是100,超了一定会报错,你的程序处理1MS 就可以是1000并发



总结:要结合你的数据库操作的处理能力,和合理的并发数 ,和你同时开启连接对象的数量不超过 你的连接池上线。

连接池默认是100



还有数据库的sleep没有清空问题,这个是ado正常的机质,close只会将状态改为 sleep,sleep是处于休息状态,当有数据库连接创建的时候会找有没有 sleep的对象,如果有就叫醒当前sleep对象,没有新创建一个连接对象,所以这种机质的存在 sleep数量并不会无限增长


sleep如果空闲过多数据库会定时清理







收藏到朋友圈: