sqlsugar 开启事务问题 返回

SqlSugar 处理完成
34 242

大佬,请问下,这个ISqlSugarClient注册的是作用域的生命周期

builder.Services.AddScoped<ISqlSugarClient>,那我想请问下,是不是在同一个作用域(也就是同一次请求里面),用的数据库连接SqlConnection是不是同一个?

因为之前用ado的时候,遇到过这样的问题,就是在同一个连接中,上面是没有使用事务的,单纯就是查询,然后查询过后使用事务,如下图:

这时候使用事务的第一个操作就报错:------如果分配给命令的连接位于本地挂起事务中,ExecuteReader 要求命令拥有事务。命令的 Transaction 属性尚未初始化

后面百度查询到说是因为在同一个连接中,如果开启了事务,那么所有的数据库操作即使是查询,也得带上事务transaction

01cb0426a17d6181d0c07a2d8fb3f08.png


那我想请问下,这个ISqlSugarClient注册的是作用域的生命周期,如果都是同一个连接的话,为什么不会出现这个问题呢?如下图:

1719969892475.jpg

麻烦大佬看看这个是什么原理呢?

热忱回答34

  • 原生对象是你自个new sqlconnection和sqlsugar有什么关系,没有看懂

    0 回复
  • bulkcopy有些库不支持事,你这代码很乱。为什么还有原生对象

    0 回复
  • @fate sta:大佬,我的问题,我没描述清楚,第一个图是用的原生的ado,会报错,如果在同一个连接中,开启了事务,第一个查询没用事务的话,就会报错------如果分配给命令的连接位于本地挂起事务中,ExecuteReader 要求命令拥有事务。命令的 Transaction 属性尚未初始化

    然后第二个图是用的sqlsugarclient,也是一样的操作,但是不会报错,不知道为什么?注册的sqlsugarclient是作用域生命周期,那是不是同一个请求范围内都是使用的同一个连接啊?

    0 回复
  • @fate sta:是的,就是想问下,注册的sqlsugarclient是作用域生命周期,那是不是同一个请求范围内都是使用的同一个SqlConnection连接呢?

    0 回复
  • 不一样,sqlsugar是sqlsugar ,原生是原生,都是一个对象

    0 回复
  • @fate sta:都是一个对象,大佬指的是什么意思呢?没怎么看明白,底层都是需要ado的,就是SqlConnection原生对象的,意思是说SqlSugarClient注册的生命周期,跟这个SqlConnection没关系的是吗?

    0 回复
  • @fate sta:那大佬,比方说SqlSugarClient注册的生命周期是作用域的话,那每次的CRUD用的是否是同一个连接对象呢?

    0 回复
  • IOC拿是一个对象

    0 回复
  • 要通过IOC获取

    0 回复
  • @fate sta:是通过IOC获取的ISqlSugarClient,那这样我就有个疑问了,如果说这种情况下获取到的连接对象是同一个的话,那在开启了事务的情况下,那这里面的所有命令都得带上事务才行吧,不然会报错,但是下面这种写法

    image.png

    就不会报错,能正常执行,这是为什么呢?因为上面那个没用事务,正常不是会提示报错:---如果分配给命令的连接位于本地挂起事务中,ExecuteReader 要求命令拥有事务。命令的 Transaction 属性尚未初始化

    0 回复
  • 没听懂,有问题写个报错DEMO 

    0 回复
  • @fate sta:大佬,就是说,sqlsugar底层最终也是基于ado的那种方式来实现的,就是ado下面这种写法

    using (var con = new SqlConnection(conString))

    {

        if (con.State != ConnectionState.Open)

        {

            con.Open();

        }

        using (SqlTransaction tr = con.BeginTransaction())

        {

            using (SqlCommand cmd = new SqlCommand(sql.ToString(), con))

            {

                //cmd.Transaction = tr;//将事务赋值给command就可以了

                var result = cmd.ExecuteNonQuery();

                if (result > 1)

                {

                    tr.Commit();

                }

                else

                {

                    tr.Rollback();

                }

            }

        }

    }

    cmd.Transaction = tr;----这个如果不写就会报错:如果分配给命令的连接位于本地挂起事务中,ExecuteReader 要求命令拥有事务。命令的 Transaction 属性尚未初始化

    那sqlsugarclient,我截图出来的那个地方,就是相当于这样,上面那个查询没有使用事务,下面的更新使用了事务,那这里的查询,跟下面的更新,是否用的是同一个connection对象呢?主要是想问这个,听大佬说的是同一个connection对象,那这样应该会报错的才对

    image.png

    0 回复
  • @fate sta:就是如果在同一个连接下,如果开启了事务,那么所有的操作都必须带上事务,但是sqlsugarclient看上去并不是这样,所以才有疑问,这两个操作是否是同一个连接下的?

    0 回复
  • @梦幻★华尔兹sqlsugarclient = sqlconnetion 明白了吗? 这2个相等的

    0 回复
  • 还有疑问提供DEMO

    0 回复
  • @fate sta:这样说明白的,就是只要是同一个sqlsugarclient,那就是同一个sqlconnection,但是这个地方就不懂了,这里的sqlsugarclient生命周期是作用域的,相当于都是同一个sqlsugarclient,也就是同一个sqlconnection,那前面那个查询没有开启事务(也就是没有带上Transaction),后面那个更新开启了事务(带上了Transaction),这样会报错的才对,这里没明白大佬

    image.png

    0 回复
  • @梦幻★华尔兹: 局部代码我没办法给你看问题,提供完整的的

    0 回复
  • 从IOC注入,还有API最上层到最下层

    0 回复
  • sugardemo.zip

    @fate sta:大佬,精简后的demo给你了,控制器就是直接调用的UserService的,

    这样说明白的,就是只要是同一个sqlsugarclient,那就是同一个sqlconnection,但是这个地方就不懂了,这里的sqlsugarclient生命周期是作用域的,相当于都是同一个sqlsugarclient,也就是同一个sqlconnection,那前面那个查询没有开启事务(也就是没有带上Transaction),后面那个更新开启了事务(带上了Transaction),这样会报错的才对,这里没明白大佬

    ----就是想知道这个问题是什么原因

    0 回复
  • image.png

    这个注入错的不是scoped

    0 回复
  • 仓储和ORM都要scoped ,提供完整DEMO ,并且能跑的

    0 回复
  • @fate sta:大佬,你看看我这个demo,有两个问题,我都写上去了,大佬看看,注册的是瞬时生命周期,我觉得跟这个没关系的,大佬看看,数据库脚本也在了

    TestSugar.zip


    0 回复
  • image.png

    异步要返回task

    0 回复
  • 否则await将会失败,导致出现线程问题

    0 回复
  • 多检查一下你的代码,异步方法不能有一个void存在,不然就会出现线程问题

     

    0 回复
  • 另外这个代码可以简化一下

    image.png

    0 回复
  • @fate sta:对的大佬,这个我后面想到了,是返回的问题,返回void就不会等待了,导致reader读取还没结束连接就关了

    0 回复
  • @fate sta:但是大佬,这个问题我没搞明白,就是原生的ado,在同一个连接下,多个sql命令,如果开启了事务的话,那所有的sql命令都要带上事务,否则就会报错,这个地方也是相当于这样,为什么不报错啊?是不是每次执行sql命令的时候对应的连接都不是同一个啊?

    0 回复
  • @fate sta:这个跟sqlsugarclient的生命周期没关系的吧?

    0 回复
  • @梦幻★华尔兹:有问题提供demo讲不清楚,还有要用scope注入不要用瞬发,瞬发跨仓储事务会有问题

    0 回复
  • @fate sta:第二个问题知道了大佬,ado没有那个问题,应该是我搞错了

    0 回复
  • @fate sta:瞬时跨仓储事务会有什么问题啊?是事务不一致,导致部分提交成功,部分提交失败吗?

    0 回复
  • @梦幻★华尔兹:  A类中有sqlsugar  B类中也有sqlsugar瞬时就不是一个对象,事务会有问题

    0 回复
  • scope保证在同一个请求不同类中的IOC是同一个对象

    0 回复