操作筛选器的 1 个应用实例:自动启用事务

简介: 操作筛选器的 1 个应用实例:自动启用事务

前言

在数据库操作过程中,有一个概念是绕不开的,那就是事务。

事务能够确保一系列数据库操作要么全部成功提交,要么全部失败回滚,保证数据的一致性和完整性。

在 Asp.Net Core Web API 中,我们可以使用操作筛选器给所有的数据库操作 API 加上事务控制,省心又省力,效果还很好。

看看 Step By Step 步骤是如何实现上述功能的。

Step By Step 步骤

  1. 创建一个 ASP.NET Core Web API 项目
  2. 引用 EF Core 项目 BooksEFCore
  1. 打开 appsettings.json,添加数据库连接串
{
  "Logging": {
  "LogLevel": {
    "Default": "Information",
    "Microsoft.AspNetCore": "Warning"
  }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
  "Default": "Server=(localdb)\\mssqllocaldb;Database=TestDB;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

4.创建一个自定义的 Attribute,用于给无需启用事务控制的操作方法

[AttributeUsage(AttributeTargets.Method)]
public class NotTransactionalAttribute:Attribute
{
}

5.编写自定义的操作筛选器 TransactionScopeFilter,用于自动启用事务控制(留意注释

using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Reflection;
using System.Transactions;
public class TransactionScopeFilter : IAsyncActionFilter
{
  public async Task OnActionExecutionAsync(
    ActionExecutingContext context, 
    ActionExecutionDelegate next)
  {
    bool hasNotTransactionalAttribute = false;
    if (context.ActionDescriptor is ControllerActionDescriptor)
    {
      var actionDesc = (ControllerActionDescriptor)context.ActionDescriptor;
      //判断操作方法上是否标注了NotTransactionalAttribute
      hasNotTransactionalAttribute = actionDesc.MethodInfo.IsDefined(typeof(NotTransactionalAttribute));
    }
    //如果操作方法标注了NotTransactionalAttribute,直接执行操作方法
    if (hasNotTransactionalAttribute)
    {
      await next();
      return;
    }
    //如果操作方法没有标注NotTransactionalAttribute,启用事务
    using var txScope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);
    var result = await next();
    if (result.Exception == null)
    {
      txScope.Complete();
    }
  }
}

6.打开 Program.cs,注册这个操作筛选器

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// 注册数据库服务
builder.Services.AddDbContext<MyDbContext>(opt => {
  string connStr = builder.Configuration.GetConnectionString("Default");
  opt.UseSqlServer(connStr);
});
// 注册自动启用事务过滤器
builder.Services.Configure<MvcOptions>(opt => { 
  opt.Filters.Add<TransactionScopeFilter>();
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
  app.UseSwagger();
  app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

7.开控制器,增加一个用于测试的操作方法(留意注释

using Microsoft.AspNetCore.Mvc;
namespace 自动启用事务的筛选器.Controllers
{
  [ApiController]
  [Route("[controller]/[action]")]
  public class TestController : ControllerBase
  {
    private readonly MyDbContext dbCtx;
    public TestController(MyDbContext dbCtx)
    {
      this.dbCtx = dbCtx;
    }
    [HttpPost]
    public async Task Save()
    {
      dbCtx.Books.Add(new Book { Id = Guid.NewGuid(), Name = "1", Price = 1 });
      await dbCtx.SaveChangesAsync();
      dbCtx.Books.Add(new Book { Id = Guid.NewGuid(), Name = "2", Price = 2 });
      await dbCtx.SaveChangesAsync();
      // 以上代码能够正确地插入两条数据
      // 如果启用以下代码抛出异常,将不会插入数据
      // 说明事务起作用,数据被回滚了
      // throw new Exception();
    }
  }
}


目录
打赏
0
0
0
0
37
分享
相关文章
可信计算平台与安全芯片扫盲文
可信计算平台与安全芯片扫盲文
367 0
【C++】sort()、stable_sort()和partial_sort()排序函数详解
【C++】sort()、stable_sort()和partial_sort()排序函数详解
438 0
阿里云飞天洛神云网络子系统“齐天”:超大规模云网络智能运维的“定海神针”
阿里云飞天洛神云网络子系统“齐天”:超大规模云网络智能运维的“定海神针”
138 3
使用Java构建实时数据处理流程
使用Java构建实时数据处理流程
java基础:map遍历使用;java使用 Patten 和Matches 进行正则匹配;后端传到前端展示图片三种情况,并保存到手机
这篇文章介绍了Java中Map的遍历方法、使用Pattern和matches进行正则表达式匹配,以及后端向前端传输图片并保存到手机的三种情况。
107 1
|
10月前
|
KVM虚拟机的克隆
这篇文章介绍了如何使用KVM虚拟机进行完整克隆和链接克隆,包括手动克隆和使用virt-clone工具克隆的方法,以及如何编写脚本来实现自动化克隆和删除虚拟机。
317 3
KVM虚拟机的克隆
端口被占用 --- 解决方案
端口被占用 --- 解决方案
197 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问