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

同一请求(作用域)下,用UnitOfWorkManager管理freeSql多数据源事务提交 #2

Open
ROMYIM opened this issue Aug 4, 2022 · 4 comments

Comments

@ROMYIM
Copy link

ROMYIM commented Aug 4, 2022

测试了一下,一个UnitOfWorkManager只能对一个数据源连接管理事务。
即使我用FreeSqlCloud<>作为UnitOfWorManager的依赖注入项,它默认会对第一个注册的数据源连接管理事务。
在切换数据源后,手动指定transaction则以第一个的数据源transaction为准。
针对多数据源的FreeSqlCloud<>可不可以有一个对应的多数据源UnitOfWorkManager同时控制多个数据连接的事务操作,一起提交或一起回滚。

@2881099
Copy link
Owner

2881099 commented Aug 4, 2022

这是因为注入方式导致的,UnitOfWorkManager 是 Scoped 类型,在 aspnet core Scope 周期内,创建 UnitOfWorkManager 可能在 FreeSqlCloud.Change 之前确定了 IFreeSql。

所以关键要看两者顺序问题。

UnitOfWorkManager 确实只支持与一个数据库进行事务交互,一般在同一个 aspnet core Scope 范围内也只会操作一个数据库,多库事务应该用 TCC 类似的分布式事务。

@2881099
Copy link
Owner

2881099 commented Aug 4, 2022

解决办法,应该在 aspnet core 中间件确定 FeeSqlCloud Change 对应的数据库之前,不要依赖反转 Repository 等与 UnitOfWorkManger 有关的对象,因为会导致 UnitOfWorkManager 创建时 IFreeSql 并非与实际数据库关联。

@ROMYIM
Copy link
Author

ROMYIM commented Aug 4, 2022

其实我主要是想对多数据源做一个统一的事务控制,一起提交或一起回滚。

@2881099
Copy link
Owner

2881099 commented Aug 4, 2022

如果 FreeSqlCloud 是有限的数量,并且使用的 AOP 事务,可以尝试以下伪代码:

class UnitOfWorkManager_1 : UnitOfWorkManager
{
    public UnitOfWorkManager1(IFreeSql fsql) : this(fsql.Change("db1")) { }
}
class UnitOfWorkManager_2 : UnitOfWorkManager
{
    public UnitOfWorkManager1(IFreeSql fsql) : this(fsql.Change("db2")) { }
}

// 手工绑定 UnitOfWorkManager_2
class TopicRepository : BaseRepository
{
    public TopicRepository(UnitOfWorkManager_2 uowManger) :  : this(uowManger?.Orm, null, null)
    {
            uowManger?.Binding(this);
    }
}

services.AddSingleton<IFreeSql>(fsql);
services.AddScoped<UnitOfWorkManager>(() => new UnitOfWorkManager_1(fsql.Change("db1")));
services.AddScoped<UnitOfWorkManager_2>();
services.AddScoped //按规则批量注入 Repository

// AOP 事务
[Transactional("db1")]
[Transactional("db2")]
public void Xxx()
{
}

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