需要事务才能使用TranLock,明明用了 返回

public async Task<(bool success, string msg)> TranAsync(Func<Task<(bool success, string msg)>> func) { string? msg; bool result = false; try { await _db.BeginTranAsync(); var m = await func(); await _db.CommitTranAsync(); msg = m.msg; result = true; } catch (Exception e) { await _db.RollbackTranAsync(); _logger.Log(LogLevel.Error, e, e.Message); msg = e.Message; } return new(result, msg); }
定义
protected BaseService( ISqlSugarClient db, IMapper mapper, ILogger logger ) { _logger = logger; _db = db.AsTenant(); _defaultDb = _db.GetConnectionScope("DefaultDb").CopyNew(); _logDb = _db.GetConnectionScope("LogDb").CopyNew(); _mapper = mapper; }
执行任何func()使用.TranLock(DbLockType.Wait)都会报错“需要事务才能使用TranLock”
热忱回答(37)
-
厂口日成 VIP0
2周前管理员大大能不能回答一下?
0 回复 -
fate sta VIP0
2周前用这个东西需要事务
0 回复 -
fate sta VIP0
2周前0 回复 -
fate sta VIP0
2周前你都copynew了就不在一个事务里面了
0 回复 -
厂口日成 VIP0
2周前直接在db上copynew呢?
0 回复 -
fate sta VIP0
2周前@厂口日成:这种事务应该去掉copynew
0 回复 -
fate sta VIP0
2周前这个地方不应该有copyNew()
0 回复 -
fate sta VIP0
2周前copynew出来的对象是不受主db事务控制的
0 回复 -
fate sta VIP0
2周前1.异步方法不写await 需要db替换成db.CopyNew() ,不想加CopyNew就需要排查是否有漏掉await,一个不能少。
2.使用await 返回值必须有Task,不能是Void 这种(表达式返回值只能Task 例如 List.Foreach 可以用原生foreach替换List.Foreach) ,特别嵌套方法要认真找,不想找就CopyNew解决
3.Task.WhenAll 、 ParallelAsync 和 第三方定时任务库 使用 db.CopyNew()
也就红色标题来的地方是需要用到copynew的其他方可以通过修改代码不需要copynew
0 回复 -
厂口日成 VIP0
2周前@fate sta:我也不想有copynew,之前没有加的时候,经常出现各种异常问题
0 回复 -
fate sta VIP0
2周前@厂口日成:看上面的文档处理,就3种情况
0 回复 -
fate sta VIP0
2周前@fate sta:还有疑问可以提供可以重现DEMO
0 回复 -
厂口日成 VIP0
2周前@fate sta:重现demo后端就是去掉copynew,然后前端在短时间内调用几个接口,就会出现有一两个接口报错。有三种:
中文提示 : 连接数据库过程中发生错误,检查服务器是否正常连接字符串是否正确,错误信息:Unable to cast object of type 'Microsoft.Data.ProviderBase.DbConnectionClosedConnecting' to type 'Microsoft.Data.SqlClient.SqlInternalConnectionTds'.DbType=\"SqlServer\";ConfigId=\"DefaultDb\".\r\nEnglish Message : Connection open error . Unable to cast object of type 'Microsoft.Data.ProviderBase.DbConnectionClosedConnecting' to type 'Microsoft.Data.SqlClient.SqlInternalConnectionTds'.DbType=\"SqlServer\";ConfigId=\"DefaultDb\"
前后端分离的情况下机会每次都有,偶尔有一次正常。
0 回复 -
厂口日成 VIP0
2周前直接用swagger界面单个点击测试没有这种情况
0 回复 -
fate sta VIP0
2周前@厂口日成:需要提供完整DEMO
0 回复 -
厂口日成 VIP0
2周前线程安全问题,只能放弃跨库事务了,我用apifox测试,开多个线程就能复现错误。
0 回复 -
fate sta VIP0
2周前@厂口日成:你不提供代码我是没办法给你找问题的,肯定你用错了,目前所有用户只要提供DEMO 100%在我说的3条之内
0 回复 -
fate sta VIP0
2周前并且你提供DEMO自测能重现的
0 回复 -
厂口日成 VIP0
2周前启动后用任意工具开多线程测试就可以复现结果,我开了5个线程。
0 回复 -
fate sta VIP0
2周前0 回复 -
fate sta VIP0
2周前这个代码要这样改
0 回复 -
fate sta VIP0
2周前十万循环你插死了也插不完。要改成批量
0 回复 -
fate sta VIP0
2周前你测试应该用 正常数量的数据插入和查询,设置每1秒请求 200左右发请求,能重现的
0 回复 -
厂口日成 VIP0
2周前不要测试插入啊,插入没有报错,就测试两个get就可以了
插入我手动运行了一次,多线程测试我只运行了上图这个,之前发的三个错误就会频繁出现,如果用copynew就没有问题
0 回复 -
fate sta VIP0
2周前找到问题了
这些建表代码不能写在这里面
0 回复 -
fate sta VIP0
2周前建库建表怎么写到每次请求里面
0 回复 -
fate sta VIP0
2周前0 回复 -
fate sta VIP0
2周前不对你还有地方写错了
0 回复 -
fate sta VIP0
2周前要改成这个
并且改成单例注入
0 回复 -
fate sta VIP0
2周前SqlSugarScope 注入改成单例
0 回复 -
fate sta VIP0
2周前这个是错的,你虽然SqlSugarClient是AddScope,你每次都是拿 sqlugar这个对象 没有委托里面new
正确应该是 (i=>new SqlSugarClient)
0 回复 -
fate sta VIP0
2周前还有codefirst代码不要每次请求
0 回复 -
fate sta VIP0
2周前AddScope (i=>new SqlSugarClient) 这是OK
AddScope (i=>变量) 这是错误的 ,明白了吗
0 回复 -
fate sta VIP0
2周前只有单例注入SqlSugarScope才能用变量
0 回复 -
厂口日成 VIP0
2周前建库建表是在每次启动的时候,后面那个我改一下试试
0 回复 -
fate sta VIP0
2周前@厂口日成:建库和建表不能写在里面,每请求这样大量浪费性能你可以先注释掉
0 回复 -
厂口日成 VIP0
2周前好的
0 回复