DotNetNext / SqlSugar

.Net aot ORM Fastest ORM Simple Easy VB.NET Sqlite orm Oracle ORM Mysql Orm 虚谷数据库 postgresql ORm SqlServer oRm 达梦 ORM 人大金仓 ORM 神通ORM C# ORM , C# ORM .NET ORM NET5 ORM .NET6 ORM ClickHouse orm QuestDb ,TDengine ORM,OceanBase orm,GaussDB orm ,Tidb orm Object/Relational Mapping
https://www.donet5.com/Home/Doc
MIT License
5.24k stars 1.33k forks source link

单例模式下后台任务AOP跨方法嵌套事务AOP只会执行一次 #1139

Closed my6521 closed 1 year ago

my6521 commented 1 year ago

问题描述 1、单例注入SqlSugarScope 2、使用hangfire执行任务 3、AOP跨方法事务 4、问题是Say2的AOP不执行 5、对于web提交不存在此问题

简码如下: services.AddSingleton<ISqlSugarClient>(sp=> new SqlSugarScope())

AOP代码

[AttributeUsage(AttributeTargets.Method)]
public class TransactionAop : AbstractInterceptorAttribute
{
    public IsolationLevel Level { get; set; } = IsolationLevel.Unspecified;

    public override async Task Invoke(AspectContext context, AspectDelegate next)
    {
        var logger = context.ServiceProvider.GetService<ILoggerFactory>().CreateLogger<TransactionAop>();

        var sqlSugarClient = context.ServiceProvider.GetService<ISqlSugarClient>();
        var notTran = sqlSugarClient.Ado.IsNoTran();
        if (!notTran)
        {
            await next.Invoke(context);
            return;
        }

        try
        {
            await sqlSugarClient.Ado.BeginTranAsync(Level);
            await next(context);
            await sqlSugarClient.Ado.CommitTranAsync();
        }
        catch (Exception ex)
        {
            await sqlSugarClient.Ado.RollbackTranAsync();

            throw;
        }
    }

hangire任务代码

public class DelayRefundJob
{
    private readonly ITestService _testService;

    public DelayRefundJob(ITestService testService)
    {
        _testService = testService;
    }

    public async Task Execute()
    {
        await _testService.Say();
    }
}

执行方法代码

public class TestService : ITestService, IScopedDependency
{
    public TestService()
    {
    }

    [TransactionAop]
    public async Task Say()
    {
        await Say2();
    }

    [TransactionAop]
    public Task Say2()
    {
        return Task.CompletedTask;
    }
}
DotNetNext commented 1 year ago

提供AOP相关代码,我这边都看不到AOP

my6521 commented 1 year ago

TransactionAop是用的aspectcore写的拦截器,不知道是不是AspectCore本身对于后台任务方法嵌套拦截的问题

DotNetNext commented 1 year ago

https://www.donet5.com/Doc/27/2537 建议这么写,不清楚你的AOP是指什么,按我文档就不会有问题

my6521 commented 1 year ago

hangfire后台任务不支持IActionFilter拦截,我使用的第三方AspectCore包写的拦截器,我先检查下吧

DotNetNext commented 1 year ago

定时任务没必要用AOP吧

my6521 commented 1 year ago

有些场景需要,比如定时任务调用的方法其他地方也要调用的情况,这个时候就需要判断跨方法是否有拦截器

my6521 commented 1 year ago

问题原因找到,是AspectCore的问题,谢谢!