Dapper的正确使用姿势 (2)

当然,这是可行的。通过AOP拦截,在方法执行前开启事务,在方法执行后提交事务就可以了。
实现如下:
需要Nuget包Autofac.Extensions.DependencyInjection Autofac.Extras.DynamicProxy

[UnitOfWork] public virtual void DelUser() { var sql = "select * from UserTemp"; var userList = dBContext.DbConnection.Query<object>(sql); var sql2 = $@"INSERT into UserTemp VALUES(0,'{DateTime.Now.ToString()}','sql2执行成功')"; dBContext.DbConnection.Execute(sql2); throw new Exception("主动报错");//验证事务 是否有效 var sq3 = $@"INSERT into UserTemp VALUES(0,'{DateTime.Now.ToString()}','sq3执行成功')"; dBContext.DbConnection.Execute(sq3); } public class UnitOfWorkIInterceptor : IInterceptor { private DBContext dBContext; public UnitOfWorkIInterceptor(DBContext dBContext) { this.dBContext = dBContext; } public void Intercept(IInvocation invocation) { MethodInfo methodInfo = invocation.MethodInvocationTarget; if (methodInfo == null) methodInfo = invocation.Method; UnitOfWorkAttribute transaction = methodInfo.GetCustomAttributes<UnitOfWorkAttribute>(true).FirstOrDefault(); //如果标记了 [UnitOfWork],并且不在事务嵌套中。 if (transaction != null && dBContext.Committed) { //开启事务 dBContext.BeginTransaction(); try { //事务包裹 查询语句 //https://github.com/mysql-net/MySqlConnector/issues/405 invocation.Proceed(); //提交事务 dBContext.CommitTransaction(); } catch (Exception ex) { //回滚 dBContext.RollBackTransaction(); throw; } } else { //如果没有标记[UnitOfWork],直接执行方法 invocation.Proceed(); } } }

完整的测试源码,会在文末提供。

SQL监控

使用EF的同学应该很多人都知道MiniProfiler,我在前些年分享EF的时候有做过简单介绍。
那么我们在执行Dapper的时候是不是也可以对生成的sql做检测和性能监控。
答案是肯定的。Git地址

Dapper的正确使用姿势

MiniProfiler监控套件还真不是一般的强。EF、MongoDB、MySql、Redis、SqlServer统统支持。
接下来我们实现对Dapper监控,导入Nuget包MiniProfiler.AspNetCore

public class ActionFilter : IAsyncActionFilter { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var profiler = MiniProfiler.StartNew("StartNew"); using (profiler.Step("Level1")) { //执行Action await next(); } WriteLog(profiler); } /// <summary> /// sql跟踪 /// 下载:MiniProfiler.AspNetCore /// </summary> /// <param></param> private void WriteLog(MiniProfiler profiler) { if (profiler?.Root != null) { var root = profiler.Root; if (root.HasChildren) { root.Children.ForEach(chil => { if (chil.CustomTimings?.Count > 0) { foreach (var customTiming in chil.CustomTimings) { var all_sql = new List<string>(); var err_sql = new List<string>(); var all_log = new List<string>(); int i = 1; customTiming.Value?.ForEach(value => { if (value.ExecuteType != "OpenAsync") all_sql.Add(value.CommandString); if (value.Errored) err_sql.Add(value.CommandString); var log = $@"【{customTiming.Key}{i++}】{value.CommandString} Execute time :{value.DurationMilliseconds} ms,Start offset :{value.StartMilliseconds} ms,Errored :{value.Errored}"; all_log.Add(log); }); //TODO 日志记录 //if (err_sql.Any()) // Logger.Error(new Exception("sql异常"), "异常sql:\r\n" + string.Join("\r\n", err_sql), sql: string.Join("\r\n\r\n", err_sql)); //Logger.Debug(string.Join("\r\n", all_log), sql: string.Join("\r\n\r\n", all_sql)); } } }); } } } }

运行效果:

Dapper的正确使用姿势

Demo源码

完整的Demo源码:https://github.com/zhaopeiym/BlogDemoCode/tree/master/Dapper_Demo/DapperDemo

结束

最后给大家推荐一个开源项目quartzui:https://github.com/zhaopeiym/quartzui
基于Quartz.NET 3.0的web管理界面,开箱即用。也可以完美运行在树莓派上。

docker run -v /fileData/quartzuifile:/app/File --restart=unless-stopped --privileged=true --name quartzui -dp 5088:80 bennyzhao/quartzui:RaspberryPi

运行在普通PC或云主机上

docker run -v /fileData/quartzuifile:/app/File --restart=unless-stopped --privileged=true --name quartzui -dp 5088:80 bennyzhao/quartzui

新建QQ群工控物联:995475200

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsppjz.html