当前位置: 首页 > news >正文

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

image

前言

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

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

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

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

Step By Step 步骤

  1. 创建一个 ASP.NET Core Web API 项目

  2. 引用 EF Core 项目 BooksEFCore

    • BooksEFCore 项目创建参见前文《EF Core 在实际开发中,如何分层?》
  3. 打开 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;//判断操作方法上是否标注了NotTransactionalAttributehasNotTransactionalAttribute = 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();}}
    }
    

总结

  1. 可以使用 TransactionScope 简化事务代码的编写。

  2. TransactionScope 是 .NET 中用来标记一段支持事务的代码的类。

  3. EF CoreTransactionScope 提供了天然的支持,当一段使用 EF Core 进行数据库操作的代码放到 TransactionScope 声明的范围中的时候,这段代码就会自动被标记为 “支持事务”

  4. TransactionScope 实现了 IDisposable 接口,如果一个 TransactionScope 的对象没有调用 Complete 就执行了 Dispose 方法,则事务会被回滚,否则事务就会被提交

  5. TransactionScope 还支持嵌套式事务,也就是多个 TransactionScope 嵌套,只有最外层的 TransactionScope 提交了事务,所有的操作才生效;如果最外层的 TransactionScope 回滚了事务,那么即使内层的 TransactionScope 提交了事务,最终所有的操作仍然会被回滚

  6. .NET Core 使用的 TransactionScope 支持的是 “最终一致性”。所谓的 “最终一致性”,指的是在一段时间内,如果系统没有发生新的更新操作,那么所有副本的数据最终会达到一致的状态。换句话说,即使在系统中的不同节点上,数据的更新可能会有一段时间的延迟,但最终所有节点的数据会达到一致的状态。

  7. 在同步代码中,TransactionScope 使用 ThreadLocal 关联事务信息;

  8. 在异步代码中,TransactionScope 使用 AsyncLocal 关联事务信息

相关文章:

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

前言 在数据库操作过程中&#xff0c;有一个概念是绕不开的&#xff0c;那就是事务。 事务能够确保一系列数据库操作要么全部成功提交&#xff0c;要么全部失败回滚&#xff0c;保证数据的一致性和完整性。 在 Asp.Net Core Web API 中&#xff0c;我们可以使用操作筛选器给…...

搭建基于Java的分布式爬虫系统

目录 前言 一、分布式爬虫系统的架构设计 二、系统搭建步骤 1. 创建爬虫项目 2. 导入相关依赖 3. 编写分布式爬虫系统的核心代码 3.1 节点管理器&#xff08;Node Manager&#xff09; 3.2 调度器&#xff08;Scheduler&#xff09; 3.3 下载器&#xff08;Downloader…...

rancher证书过期问题处理

问题 起初&#xff0c;打开rancher ui页面打不开&#xff0c;telnet rancher的服务端口也不通。查看rancher 控制节点&#xff0c;日志显示&#xff0c;X509&#xff1a;certificate has expired or is not ye valid。证书已过期 解决 现在网上大部分的解决方案都是针对的2…...

Spring Boot 中文件上传

Spring Boot 中文件上传 一、MultipartFile二、单文件上传案例三、多文件上传案例四、Servlet 规范五、Servlet 规范实现文件上传 上传文件大家用的最多的就是 Apache Commons FileUpload&#xff0c;这个库使用非常广泛。Spring Boot3 版本中已经不能使用了。代替它的是 Sprin…...

2023年06月CCF-GESP编程能力等级认证Python编程一级真题解析

一、单选题(共15题,共30分) 第1题 以下不属于计算机输出设备的有()。 A:麦克风 B:音箱 C:打印机 D:显示器 答案:A 第2题 ChatGPT 是 OpenAI 研发的聊天机器人程序,它能通过理解和学习人类的语言来进行对话,还能根据聊天的上下文进行互动,完成很多工作。请你…...

unity 使用数字图片来代替数字0到9显示

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Trackracecomplete : MonoBehaviour { /// /// 数字图片 /// [SerializeField] private Sprite[] sprites; private string _Time “23:57:49”; [Ser…...

单片机如何实现延时1ms或者1us

1us //适配主频为120MHz的单片机 void Delay_us(int16_t nus) {int32_t temp; SysTick->LOAD nus*15; //120MHzSysTick->VAL0X00;SysTick->CTRL0X01;do { tempSysTick->CTRL;}while((temp&0x01)&&(!(temp&(1<<16))));SysTick->CTRL0x0…...

全国网络安全行业职业技能大赛WP

word_sercet 文档被加密 查看图片的属性 在备注可以看到解压密码 解密成功 在选项里面把隐藏的文本显示出来 可以看到ffag easy_encode 得到一个bmp二维码 使用qr research 得到的密文直接放瑞士军刀 base32解码base64解码hex解码 dir_pcap 直接搜索flag 发现flag…...

【Python函数与模块】(7)模块的分类与好处

文章目录 一、模块分类二、模块的好处 一、模块分类 Python标准模块&#xff08;内置模块&#xff0c;标准库&#xff09; 第三方模块/库&#xff08;pypi.org&#xff09; 自定义模块 二、模块的好处 可维护性更强 方便代码重用...

如何安全地多开Facebook/Twitter/TK/Ins等账号?

随着社交媒体的普及&#xff0c;人们需要在不同平台上管理多个账号。然而&#xff0c;如何安全地多开这些账号却是一个需要关注的问题。本文将介绍如何安全地多开Facebook、twitter、YouTube、TikTok等平台账号的方法。 重要关联因素&#xff1a; 1. 隐私和安全&#xff1a;保…...

ChatGPT学python: 用json文件传参

目录 json语法最简陋版python解析语法小结 json语法最简陋版 param.json [{"Table_name": "table1","Event_name_colum": 4,"update_colum": 9},{"Table_name": "table2","Event_name_colum": 3,&quo…...

【C++航海王:追寻罗杰的编程之路】引用、内联、auto关键字、基于范围的for、指针空值nullptr

目录 1 -> 引用 1.1 -> 引用概念 1.2 -> 引用特性 1.3 -> 常引用 1.4 -> 使用场景 1.5 -> 传值、传引用效率比较 1.6 -> 值和引用作为返回值类型的性能比较 1.7 -> 引用和指针的区别 2 -> 内联函数 2.1 -> 概念 2.2 -> 特性 3 -…...

已实现:vue、h5项目如何使用echarts实现雷达图、六边形图表

说实话&#xff0c;要说图表里&#xff0c;最强的应该属于echarts了&#xff0c;不管是接入难度上&#xff0c;还是样式多样性上&#xff0c;还有社区庞大程度上&#xff0c;都是首屈一指的&#xff0c;反观有的人习惯用chart.js了&#xff0c;这个无可厚非&#xff0c;但是如果…...

JUC并发编程-四大函数式接口、Stream 流式计算、ForkJoin并行执行任务

12. 四大函数式接口 新时代的程序员&#xff1a;lambda表达式、链式编程、函数式接口、Stream流式计算 函数式接口&#xff1a;只有一个方法的接口&#xff0c;可以有一些默认的方法 如&#xff1a;Runnable接口函数 1&#xff09;Function 函数型接口 public class Functio…...

【Tomcat与网络4】Tomcat的连接器设计

目录 1 如何设计一个灵活可靠的连接器 2 主要组件介绍 在上一篇&#xff0c;我们介绍了Tomcat提供服务的整体结构&#xff0c;本文我们一起来看一下Tomcat的连接器的设计。 在前面我们提到Tomcat主要完成两个功能&#xff1a; 处理 Socket 连接&#xff0c;负责网络字节流与…...

k8s中调整Pod数量限制的方法

一、介绍 Kubernetes节点每个默认允许最多创建110个pod&#xff0c;有时可能由于主机配置扩容的问题&#xff0c;从而需要修改节点pod运行数量的限制。 即&#xff1a;需要调整Node节点的最大可运行Pod数量。 一般来说&#xff0c;只需要在kubelet启动命令中增加–max-pods参数…...

在Java中,实现扩展性通常有几种方法,其中包括接口、抽象类、插件架构和服务加载等方式

在Java中&#xff0c;实现扩展性通常有几种方法&#xff0c;其中包括接口、抽象类、插件架构和服务加载等方式。以下是如何使用接口来实现灵活的扩展和插件管理的一些基本指导&#xff1a; 定义基础接口&#xff1a; 创建一个或多个基础接口&#xff0c;这些接口定义了所有实现…...

【乳腺肿瘤诊断分类及预测】基于自适应SPREAD-PNN概率神经网络

课题名称&#xff1a;基于自适应SPREAD-PNN的乳腺肿瘤诊断分类及预测 版本日期&#xff1a;2023-06-15 运行方式: 直接运行PNN0501.m 文件即可 代码获取方式&#xff1a;私信博主或QQ&#xff1a;491052175 模型描述&#xff1a; 威斯康辛大学医学院经过多年的收集和整理&…...

蓝桥杯AT24C02问题记录

问题1&#xff1a;从这个图片上可以看出这两个在IIC的.c文件里延时时间不一样&#xff0c;第一张图使用了15个_nop_(); 12M晶振机器周期是 1/12M*121uS&#xff1b;nop()要延时1个指令周期。延时时间不对会对时序产生影响&#xff0c;时序不对&#xff0c;则AT24C02有没被使用…...

adb控制设备状态

屏幕设置 屏幕亮度 # 当前屏幕亮度 adb shell settings get system screen_brightness# 更改屏幕亮度adb shell settings put system screen_brightness屏幕休眠时间 # 当前屏幕休眠时间 adb shell settings get system screen_off_timeout#更改屏幕休眠时间 adb shell sett…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

若依登录用户名和密码加密

/*** 获取公钥&#xff1a;前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...