果糖网

SqlTransaction 已完成;它再也无法使用 返回

SqlSugar
17 162

 这个偶发性问题 怎么处理啊 


image.png


image.png


image.png

热忱回答17

  • 这个很明显是事务用完后在使用出的错



    线程安全文档 :https://www.donet5.com/Home/Doc?typeId=1224

    0 回复
  • @小杰image.png今天又出现这个了

    db使用情况:

    image.pngimage.png

    这个方法内部 就一个地方用到事务:

    image.png

    按照照目前这个状况,我这个什么情况下会导致“这个很明显是事务用完后在使用出的错” 这个异常。

    0 回复
  • @?稻草人:你可以把代码发全,这样我也不清楚你怎么写的,还有主日志的时候把SQL打上 ,不然不清楚是哪里的错,是否是这个方法

    0 回复
  • @小杰

                     public class TpManager            
                    {
                        private static Logger log = LogManager.GetCurrentClassLogger();
                        //Tplus
                        public string WMSConnnectString { get; set; }
                        public string TplusConnnectString { get; set; }
                        //TP数据源
                        public  SqlSugarClient TpInstance 
                        {
                            get
                            {
                                return new SqlSugarClient(new ConnectionConfig
                                {
                                    ConnectionString = TplusConnnectString,
                                    DbType = DbType.SqlServer,
                                    IsAutoCloseConnection = true,
                                    InitKeyType = InitKeyType.Attribute
                                });
                            }
                        }
                        /// <summary>
                        /// wms数据源
                        /// </summary>
                        public SqlSugarClient WmsInstance
                        {
                            get
                            {
                                return new SqlSugarClient(new ConnectionConfig
                                {
                                    ConnectionString = WMSConnnectString,
                                    DbType = DbType.SqlServer,
                                    IsAutoCloseConnection = true,
                                    InitKeyType = InitKeyType.Attribute                  
                                });
                            }
                        }
            
            public async Task<DbResult<Tuple<int, int, int, int, int, int>>> InsertTest(string wareCode, Supplier supplier, string linker, string sDate, string inventoryTypeCode)
            {
                var db = WmsInstance;
                db.Ado.CommandTimeOut = 60000;
                
    
                var result = db.UseTran(() =>
                {
                    Tuple<int, int, int, int, int, int> r = null;
                    int r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0;
                    #region 存储数据
                    if (resultForproduct.Count() > 0)
                    {
                        r1 = db.Insertable<Product>(resultForproduct.ToArray()).ExecuteCommand();
                    }
                    if (resultForcustomer.Count() > 0)
                    {
                        r2 = db.Insertable<Customer>(resultForcustomer.ToArray()).ExecuteCommand();
                    }
                    if (resultForSupplier.Count() > 0)
                    {
                        r3 = db.Insertable<Supplier>(resultForSupplier.ToArray()).ExecuteCommand();
                    }
                    if (resultFororders.Count() > 0 && resultFororderDetails.Count() > 0)
                    {
                        foreach (var item in resultFororders)
                        {
                            item.Linker = linker;
                        }
                        r4 = db.Insertable<WareOrder>(resultFororders.ToArray()).ExecuteCommand();
                        r5 = db.Insertable<WareOrderDetail>(resultFororderDetails.ToArray()).ExecuteCommand();
                    }
                    if (wareStocksForWsm.Count > 0)
                    {
                        db.Ado.ExecuteCommand("truncate table Inventory");
                        r6 = db.Insertable<Inventory>(wareStocks.ToArray()).ExecuteCommand();
                    }
                    else
                    {
                        r6 = db.Insertable<Inventory>(wareStocks.ToArray()).ExecuteCommand();
                    }
                    r = new Tuple<int, int, int, int, int, int>(r1, r2, r3, r4, r5, r6);
                    #endregion
                    return r;
                }, e =>
                {
                    throw e;
                });          
                return result;
            }


    0 回复
  • @小杰:这个问题  是偶发性问题 有几天是正常的 ,当时没把主日志sql打印

    0 回复
  • @?稻草人:把这些外部方法注释掉 GetCurrentStock(wareCode, inventoryTypeCode) 

    0 回复
  • 大概率是你写的 外部方法引起的 GetOrderDetailsAsync ,内部方法都OK

    0 回复
  • 还有sqlsugar版本升级到最新

    0 回复
  • @小杰:外部方法 都是Query  没用到事务,就贴的方法用到了 

         public async Task<DbResult<Tuple<int, int, int, int, int, int>>> Insert(string wareCode, Supplier supplier, string linker, string sDate, string inventoryTypeCode)
            {
                var db = WmsInstance;
                db.Ado.CommandTimeOut = 60000;
                
    
                var result = db.UseTran(() =>
                {
                    Tuple<int, int, int, int, int, int> r = null;
                    int r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0;
                    #region 存储数据
                    if (resultForproduct.Count() > 0)
                    {
                        r1 = db.Insertable<Product>(resultForproduct.ToArray()).ExecuteCommand();
                    }
                    if (resultForcustomer.Count() > 0)
                    {
                        r2 = db.Insertable<Customer>(resultForcustomer.ToArray()).ExecuteCommand();
                    }
                    if (resultForSupplier.Count() > 0)
                    {
                        r3 = db.Insertable<Supplier>(resultForSupplier.ToArray()).ExecuteCommand();
                    }
                    if (resultFororders.Count() > 0 && resultFororderDetails.Count() > 0)
                    {
                        //var s = db.Insertable<WareOrder>(resultFororders.ToArray()).ToSql();
                        foreach (var item in resultFororders)
                        {
                            item.Linker = linker;
                        }
                        r4 = db.Insertable<WareOrder>(resultFororders.ToArray()).ExecuteCommand();
                        r5 = db.Insertable<WareOrderDetail>(resultFororderDetails.ToArray()).ExecuteCommand();
                    }
                    if (wareStocksForWsm.Count > 0)
                    {
                        db.Ado.ExecuteCommand("truncate table Inventory");
                        r6 = db.Insertable<Inventory>(wareStocks.ToArray()).ExecuteCommand();
                    }
                    else
                    {
                        r6 = db.Insertable<Inventory>(wareStocks.ToArray()).ExecuteCommand();
                    }
                    r = new Tuple<int, int, int, int, int, int>(r1, r2, r3, r4, r5, r6);
                    #endregion
                    return r;
                }, e =>
                {
                    throw e;
                });
    
                return result;
            }


    0 回复
  • @小杰:只在最后存储数据用了事务

    0 回复
  • 11点后 又出现2次  我吧异常时sql语句打印出来  再观察看看

    2021-04-08 09:37:14.1647 | 此 SqlTransaction 已完成;它再也无法使用。 

    2021-04-08 10:16:40.9164 | 此 SqlTransaction 已完成;它再也无法使用。 

    2021-04-08 11:00:01.9328 | 此 SqlTransaction 已完成;它再也无法使用。 

    2021-04-08 11:46:19.8232 | 此 SqlTransaction 已完成;它再也无法使用。 


    0 回复
  • , e =>
                {
                    throw e;
                }

    这个是什么语法,我不记得我文档上有这用法

    0 回复
  •  var result = db.Ado.UseTran(() =>
                      {
                        var beginCount = db.Queryable<Student>().ToList();
                        db.Ado.ExecuteCommand("delete student");
                        var endCount = db.Queryable<Student>().Count();
                        throw new Exception("error haha");
                      });
                      
     if(!result.IsSuccess)
     {
        throw result.ex;
     }

    这才是标准用法

    0 回复
  • @小杰:下面是官方源码,这个e不是委托吗 所以我的 ,e=>{ throw e} 合适啊 文档并没逐个写所有的使用方法。

    image.png

    0 回复
  • @?稻草人:你就按最简单代码测吧,一个方法可以看到全部

    0 回复
  • 有问题发一个方法的代码就行了

    0 回复
  • @小杰image.png一样的效果的,由于偶发性问题,我现在吧aop error 事件开了,也更新sqlsugar到最新版  看是否还会出现这个问题,之前事务问题 频繁出现,我检查到是因为

    // Quartz.Net
        [DisallowConcurrentExecution]
        public class ExecuteJob : IJob

     这块没控制并发导致的,控制并发后不再频繁出现 ,这也是隔了10多天 又出现这个问题,不过不是特别频繁。

    0 回复

学习文档