SqlSugarScope采用依赖注入无论异步还是同步都会报数据库连接关闭的错误。 返回

SqlSugar
4 233
该叫什么 PA 发布于1个月前
悬赏:0 飞吻

之前用官方推荐的services.AddScoped<ISqlSugarClient>()方式注册,异步总是出报错连接已经关闭的错误,改为services.AddTransient<ISqlSugarClient>()错误依旧。

官方推荐用SqlSugarScope,但是最终还是折腾SqlSugarClient,因为5%的优势


经过不断测试,我重新封装下面的方法,异步模拟测试上千次都没有报错了,我感觉写法也差不多,但为啥这种就没有错误?底层原理有没有人解释一下。

using Auth.Core.Cache;
using Auth.Core.Configuration;
using HuaTuo.Utils;
using HuaTuo.Utils.Snowflake;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using System;
namespace Auth.Core
{

    [Service(ServiceLifetime.Scoped)]
    public class DbContext:IDbContext
    {
        SqlSugarClient _db;
        IdWorker _idWorker;
        RedisHelper _redisHelper;
        GlobalConfig _globalConfig;
        public  DbContext(RedisHelper redisHelper, GlobalConfig globalConfig, IdWorker idWorker)
        {
            this._redisHelper = redisHelper;
            this._globalConfig = globalConfig;
            this._idWorker = idWorker;
            _db = new SqlSugarClient(new ConnectionConfig()
            {
                //主库连接字符串
                ConnectionString = _globalConfig.DbConnection.ConnectionString,
                //数据库类型
                DbType = (DbType)Enum.Parse(typeof(DbType), _globalConfig.DbConnection.DbType),
                //自动释放和关闭数据库连接,如果有事务事务结束时关闭,否则每次操作后关闭
                IsAutoCloseConnection = true,
                //从库配置
                SlaveConnectionConfigs = _globalConfig.DbConnection.SlaveConnectionConfigs,
                ConfigureExternalServices = new ConfigureExternalServices()
                {
                    DataInfoCacheService = new SqlSugarCache(_redisHelper) //配置二级缓存类
                }
            });
            //Sugar提供的面向切面方法
            _db.Aop.DataExecuting = (oldValue, entityInfo) =>
            {
                //var user= httpContextAccessor.HttpContext.User.Claims.get
                if (entityInfo.PropertyName.ToLower() == "id" && entityInfo.OperationType == DataFilterType.InsertByObject/* && !entityInfo.EntityColumnInfo.IsIdentity*/)
                {
                    entityInfo.SetValue(_idWorker.NextId());//修改Id为雪花id值
                }
            };
        }

        /// <summary>
        /// 获取SqlSugarClient
        /// </summary>
        /// <returns></returns>
        public SqlSugarClient DbClient()
        {
            return _db;
        }

        /// <summary>
        /// 开启事务
        /// </summary>
        public void BeginTran()
        {
            DbClient().BeginTran();
        }

        //提交事务
        public void CommitTran()
        {
            try
            {
                DbClient().CommitTran();
            }
            catch (Exception ex)
            {
                DbClient().RollbackTran();//回滚
                throw;
            }
        }

        /// <summary>
        /// 回滚
        /// </summary>
        public void RollbackTran()
        {
            DbClient().RollbackTran();
        }
    }
}


热忱回答4

  • PA PA VIP0
    1个月前

    我发现SqlSugarClient如果用net core默认的依赖注入方式,无论异步或同步,只要前端多个ajax发起请求,都会报错,但是通过new方式构造就不会出错。

    有图为证:

    1、前端循环请求

    2.png

    报错:

    1.png

    后端还用的是同步方法

            /// <summary>
            /// 获取用户池数据
            /// </summary>
            /// <returns></returns>
            [HttpGet]
            public  ResponseData GetList()
            {
                ResponseData responseData = new ResponseData();
                ListData<UserPool> listData = new ListData<UserPool>();
                listData.List = _userPoolServices.QueryList();
                responseData.Data = listData;
                return responseData;
            }

    Service层,ISqlSugarClient在Startup.cs中配置了依赖注入。

            ISqlSugarClient _sqlSugarClient;
            public UserPoolServices(ISqlSugarClient sqlSugarClient) 
            {
                _sqlSugarClient = sqlSugarClient;
            }
    
            /// <summary>
            /// 查询列表
            /// </summary>
            /// <param name="orderBy"></param>
            /// <returns></returns>
            public  IEnumerable<UserPool> QueryList(string orderBy = "id desc")
            {
                return _sqlSugarClient.Queryable<UserPool>().OrderBy(orderBy).ToList();
            }


    所以我得出一个结论SqlSugarClient不能采用默认依赖注入方式,无论同步还是异步,只要前端同时发起多个同样的请求,都会报错,net版本采用的是net5.0

    官方技术人员能解答一下原因吗?

    0 回复
  • PA PA VIP0
    1个月前

    1.png

    一点捐赠表示诚意,开源不易

    0 回复
  • fate sta fate sta VIP0
    1个月前

    SqlSugarClient : db不能跨上下文使用,每个上下文需要new出一个新对象(和Dapper一样) , 这个写的很明白了 ,


    如果替换SqlSugarScope好了,那么证明你的线程有问题  ,Scope底层就是SqlSugarClient 没什么疑问的

    0 回复
  • fate sta fate sta VIP0
    1个月前

    SqlSugarClient 注入是scope并不代表线程安全,因你赋值给了变量DbConext 所以DbContext只跨线程就有问题, 我看你这个代码DbContext也做了处理这样就不会有问题了


        [Service(ServiceLifetime.Scoped)]
        public class DbContext:IDbContext


    0 回复