Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何使用EnableRetryOnFailure #258

Open
NuxYoung opened this issue Nov 1, 2023 · 9 comments
Open

如何使用EnableRetryOnFailure #258

NuxYoung opened this issue Nov 1, 2023 · 9 comments

Comments

@NuxYoung
Copy link

NuxYoung commented Nov 1, 2023

因数据库采用了AlwaysOn作为高可用方案,主从切换的时候会导致数据库连接不可用。在未使用ShardingCore前,采用了EnableRetryOnFailure,允许重试。但是使用以后,执行SaveChangesAsync()的时候,会报异常

The configured execution strategy 'SqlServerRetryingExecutionStrategy' does not support user-initiated transactions. Use the execution strategy returned by 'DbContext.Database.CreateExecutionStrategy()' to execute all the operations in the transaction as a retriable unit.

想问下有合适的解决方案吗?以下是我的配置:

services.AddShardingDbContext<BoxStickerContext>()
    .UseRouteConfig(op =>
    {
        // 此处配置需要分表的表名
        op.AddShardingTableRoute<BoxCodeVirtualTableRoute>();
    }).UseConfig((sp, op) =>
    {
        op.UseShardingQuery((conn, builder) =>
        {
            builder.UseSqlServer(conn, builder =>
            {
                builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
            });
        });
        op.UseShardingTransaction((conn, builder) =>
        {
            builder.UseSqlServer(conn, builder =>
            {
                builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
            }); 
        });
        op.AddDefaultDataSource("BoxStickerContext", configuration.GetConnectionString("BoxStickerConnection"));
        op.UseShardingMigrationConfigure(op =>
        {
            op.ReplaceService<IMigrationsSqlGenerator, ShardingMigrationsSqlGenerator<BoxStickerContext>>();
        });
    }).AddShardingCore();
@xuejmnet
Copy link
Collaborator

xuejmnet commented Nov 1, 2023

sharding-core的savechange如果不分库本质就是用的同一个sqlconnection,然后将同一个connection传入到2个或者3个dbcontext,foreach进行分别提交
image

image

代码本质就是这个

image

官方文档
image

https://learn.microsoft.com/zh-cn/ef/core/saving/transactions

您可以自己试试看,因为这个错误应该不是我这边抛出的,具体我也是按照官方文档来实现的所以也没有试过这个配置,你可以先自己试试,我后续看看这个问题 : )

@xuejmnet
Copy link
Collaborator

xuejmnet commented Nov 1, 2023

具体还没有看过EnableRetryOnFailure这个配置有可能是针对单个dbcontext的而非所有用相同连接的dbcontext如果是的话需要查看对应的方法让所有dbcontext都重试或者是可以的,我还有一个问题想问下是否在主从切换的时候才会报错,平时使用时不会呢

@NuxYoung
Copy link
Author

NuxYoung commented Nov 1, 2023

我是最近生产环境的一次数据库主从切换才发现这个项目没添加EnableRetryOnFailure,但是在UseShardingTransaction配置中加入了EnableRetryOnFailure就会报错,查询没有问题。从日志看起来,涉及到分表的实体,在进行插入、更新的时候都会抛出这个异常

@xuejmnet
Copy link
Collaborator

xuejmnet commented Nov 1, 2023

@NuxYoung 好的我晚点本地尝试一下,实在不好意思给你带来的问题深表歉意

@NuxYoung
Copy link
Author

NuxYoung commented Nov 1, 2023

@NuxYoung 好的我晚点本地尝试一下,实在不好意思给你带来的问题深表歉意

没事,框架开源已经很好了,也需要我们共同去完善,这也是开源的目的嘛^_^

@NuxYoung
Copy link
Author

NuxYoung commented Nov 2, 2023

非常抱歉,我定位到问题了,开发的伙伴没有遵循好规则,导致_currentShardingDbContext.GetShardingExecutor().IsMultiDbContexttrue,然后就开启了事务执行。这个我们团队调整一下就可以了。然后我也看到Context.Database.AutoTransactionsEnabled被弃用了,后面可能需要更新为Context.Database.AutoTransactionBehavior

@xuejmnet
Copy link
Collaborator

xuejmnet commented Nov 2, 2023

@NuxYoung 嗯不过这个也不能算是你们的问题,因为IsMultiDbContext本质来讲是插入的时候跨分片了或者跨后缀表了这个可能你们并不一定能修改掉,本质还是dbcontext在多个提交时需要开事务并且无法支持多个dbcontext的共享事务问题,可能你们不让他为true也不一定有效 😂,因为业务可能会出现插入两张表或者其他情况会发生

@NuxYoung
Copy link
Author

NuxYoung commented Nov 2, 2023

@NuxYoung 嗯不过这个也不能算是你们的问题,因为IsMultiDbContext本质来讲是插入的时候跨分片了或者跨后缀表了这个可能你们并不一定能修改掉,本质还是dbcontext在多个提交时需要开事务并且无法支持多个dbcontext的共享事务问题,可能你们不让他为true也不一定有效 😂,因为业务可能会出现插入两张表或者其他情况会发生

是的,我也考虑到这个问题,如果同时操作多个context或者多张分页表,也会有报错。目前我们采用的方法是对这个业务动作先禁用事务,但这个不是最佳的解决方案

@xuejmnet
Copy link
Collaborator

xuejmnet commented Nov 3, 2023

@NuxYoung dotnet/efcore#24922 可以看下这个里面的讨论

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants