shuxinqin / Chloe

A lightweight and high-performance Object/Relational Mapping(ORM) library for .NET --C#
https://github.com/shuxinqin/Chloe/wiki
MIT License
1.52k stars 455 forks source link

如何使 Chloe 和 CAP 进行集成 #328

Closed yang-xiaodong closed 2 years ago

yang-xiaodong commented 2 years ago

背景描述

CAP 中,事务对象需要交给CAP进行提交从而在事务实现提交后对缓存消息到 Broker 的 Flush 动作,而目前的Orm大部分都有自己的事务管理对象进行事务的提交。CAP官方直接原生支持使用 ADO.NET 和 EntityFrameworkCore 进行事务集成,而对于第三方ORM则需要自行扩展,以下为 Chloe Orm 和 CAP 的 集成示例。

示例

public class ChloeTransaction : CapTransactionBase
{

    public ChloeTransaction(IDispatcher dispatcher, IDbSession session) : base(dispatcher)
    {
        DbSession = session;      
    }

    public IDbSession DbSession { get; set; }

    public override object? DbTransaction => DbSession.CurrentTransaction;

    public override void Commit()
    {
        DbSession.CommitTransaction();
        Flush();
    }

    public override Task CommitAsync(CancellationToken cancellationToken = default)
    {
        throw new NotImplementedException();
    }

    public override void Rollback()
    {
        DbSession.RollbackTransaction();
    }

    public override Task RollbackAsync(CancellationToken cancellationToken = default)
    {
        throw new NotImplementedException();
    }

    public override void Dispose()
    {
        (DbTransaction as IDisposable)?.Dispose();
    }
}
public static class Extensions
{
    public static ICapTransaction BeginTransaction(this IDbContext dbContext,
        ICapPublisher publisher, bool autoCommit = false)
    { 
        var dispatcher = publisher.ServiceProvider.GetRequiredService<IDispatcher>();
        dbContext.Session.BeginTransaction();
        var transaction =  new ChloeTransaction(dispatcher,dbContext.Session)
        {
            AutoCommit = autoCommit
        };
        return publisher.Transaction.Value = transaction;
    }
}

Sample publish with transaction

[Route("~/with/test")]
public IActionResult WithTransaction()
{
    using (_dbContext.BeginTransaction(_capBus, true))
    {
        _dbContext.Insert(new Person2() { Name = "HelloWorld" });           
        _capBus.Publish("sample.rabbitmq.mysql", DateTime.Now);
    }
    return Ok();
}

源地址: https://github.com/dotnetcore/CAP/issues/1179