SqlSugar CAP用法 返回
SqlSugar
老数据
1
947
fate sta 发布于2023/12/1
悬赏:0 飞吻
背景描述有朋友咨询(前同事)关于CAP如何和SqlSugar集成的问题,在SqlSugar文档章节 CAP事务 TCC和Saga 已经有相关描述。 本 Issue 提供一种简便的通过扩展方法来实现这一点,本思路同样适用于其他三方ORM. 在 CAP 中,事务对象需要交给CAP进行提交从而在事务实现提交后对缓存消息到 Broker 的 Flush 动作,而目前的Orm大部分都有自己的事务管理对象进行事务的提交。 CAP官方直接原生支持使用 ADO.NET 和 EntityFrameworkCore 进行事务集成,而对于第三方ORM则需要自行扩展,以下为 SqlSugar 和 CAP 的 集成示例。 定义扩展类
public class SqlSugarTransaction : CapTransactionBase{ public SqlSugarTransaction(IDispatcher dispatcher, IAdo ado) : base(dispatcher) { Ado = ado; DbTransaction = ado.Transaction; } public IAdo Ado { get; set; } public override void Commit() { Ado.CommitTran(); Flush(); } public override async Task CommitAsync(CancellationToken cancellationToken = default) { await Ado.CommitTranAsync(); Flush(); } public override void Dispose() { Ado.Dispose(); } public override void Rollback() { Ado.RollbackTran(); } public override async Task RollbackAsync(CancellationToken cancellationToken = default) { await Ado.RollbackTranAsync(); }} 使用扩展方法基于 ISqlSugarClient 对象扩展,同样也可SqlSugar提供基于 IAdo 对象扩展,由于 AsyncLocal 的问题,目前不支持异步。 public static class Extensions{ public static ICapTransaction BeginCapTransaction(this ISqlSugarClient sugarClient, ICapPublisher publisher, bool autoCommit = false) { var dispatcher = publisher.ServiceProvider.GetRequiredService<IDispatcher>(); sugarClient.Ado.BeginTran(); var transaction = new SqlSugarTransaction(dispatcher, sugarClient.Ado) { AutoCommit = autoCommit }; return publisher.Transaction.Value = transaction; }} 示例封装完成后,发送事务集成消息变得更加简单。 场景一表示在执行了系列业务操作后,才进行消息发送,此时支持自动提交事务。 场景二表示先进行消息发送,才执行业务操作,此时不能使用自动提交事务,否则发完消息后CAP会立即提交事务。 [HttpGet("test")]public IActionResult PublishWithSqlSugarTrans([FromServices] ISqlSugarClient sqlSugar, [FromServices] ICapPublisher cap){ //场景一 : 发布消息在业务代码后 using (var trans = sqlSugar.BeginCapTransaction(cap, autoCommit: true)) { try { sqlSugar.Insertable(new Persons() { Name = "jack" }).ExecuteCommand(); //throw new Exception("error"); //throw a exception to test transaction is work cap.Publish("sample.rabbitmq.sqlsugar", DateTime.Now); //发布消息在业务代码后 } catch (Exception) { trans.Rollback(); } } //场景二:发布消息在业务代码前,不能使用自动提交,否则发完消息后CAP会立即提交事务。 autoCommit must be false using (var trans = sqlSugar.BeginCapTransaction(cap, autoCommit: false)) { try { cap.Publish("sample.rabbitmq.sqlsugar", DateTime.Now); throw new Exception("error"); //throw a exception to test transaction is work sqlSugar.Insertable(new Persons() { Name = "tom" }).ExecuteCommand(); trans.Commit(); } catch (Exception) { trans.Rollback(); } } return Ok();} |
热忱回答(1)
-
fate sta VIP02023/12/10 回复