把事务封装成类似Serializable用法的特性
最近几天上班没事可做就想着整理常用的类库方法,验证、消息、分页、模版引擎、数据库操作、ini操作、文本操作、xml操作等,最后就是现在这个事务特性。
1 /// <summary> 2 /// 事务形象属性的接口 3 /// </summary> 4 internal class TransactionAspectProperty : IContextProperty, IContributeObjectSink 5 { 6 //冻结策略 7 public void Freeze(Context newContext) 8 { 9 } 10 //获取事务接口容器 11 public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink) 12 { 13 return new TransactionAspect((BaseBusinessComponent) obj, nextSink); 14 } 15 //判断是否存在策略 16 public bool IsNewContextOK(Context newCtx) 17 { 18 return true; 19 } 20 //获取特性名称 21 public string Name 22 { 23 get 24 { 25 return "TransactionAspectProperty"; 26 } 27 } 28 //获取Remoting特性名称 29 string System.Runtime.Remoting.Contexts.IContextProperty.Name 30 { 31 get 32 { 33 return "TransactionAspectProperty"; 34 } 35 } 36 }
Freeze、IsNewContextOK、Name是IContextProperty 成员 GetObjectSink是IContributeObjectSink 成员
TransactionAspectProperty继承于IContextProperty、IContributeObjectSink,用于返回权限验证消息接收器的实例TransactionAspect
1 //事务的特性 2 internal sealed class TransactionAspectAttribute : ContextAttribute 3 { 4 public TransactionAspectAttribute() : base("TransactionAspect") 5 { 6 } 7 /// <summary> 8 /// 从写父类的特性 9 /// </summary> 10 /// <param name="ccm"></param> 11 public override void GetPropertiesForNewContext(IConstructionCallMessage ccm) 12 { 13 if (ccm != null) 14 { 15 ccm.ContextProperties.Add(new TransactionAspectProperty()); 16 } 17 } 18 }
TransactionAspectAttribute继承ContextAttribute的特性
1 internal class TransactionAspect : IMessageSink 2 { 3 private BaseBusinessComponent _biz;//抽象类 4 private IMessageSink _nextSink;//消息管理 5 6 public TransactionAspect(BaseBusinessComponent biz, IMessageSink nextSink) 7 { 8 this._biz = biz; 9 this._nextSink = nextSink; 10 } 11 12 13 /// <summary> 14 /// 异步处理给定的消息。 15 /// </summary> 16 /// <param name="msg">要处理的消息。</param> 17 /// <param name="replySink"> 答复消息的答复接收器。</param> 18 /// <returns>返回 System.Runtime.Remoting.Messaging.IMessageCtrl 接口,该接口提供一种在调度异步消息之后控制这些消息的方法。</returns> 19 public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink) 20 { 21 return null; 22 } 23 /// <summary> 24 /// 检查是否存在事务 25 /// </summary> 26 /// <param name="m"></param> 27 /// <returns></returns> 28 private static bool ExistsEnableCommit(MethodBase m) 29 { 30 object[] attributes = m.GetCustomAttributes(true); 31 object[] VB_t_array_L0 = attributes; 32 for (int VB_t_i4_L0 = 0; VB_t_i4_L0 < VB_t_array_L0.Length; VB_t_i4_L0++) 33 { 34 if (RuntimeHelpers.GetObjectValue(VB_t_array_L0[VB_t_i4_L0]) is EnableCommitAttribute) 35 { 36 return true; 37 } 38 } 39 return false; 40 } 41 /// <summary> 42 /// 消息管理接口 43 /// </summary> 44 /// <param name="msg"></param> 45 /// <returns></returns> 46 public IMessage SyncProcessMessage(IMessage msg) 47 { 48 IMessage returnMessage;//通信信息 49 IMethodMessage methodMesssage = (IMethodMessage) msg;//方法的消息 50 this._biz.Rollback = false; 51 if (ExistsEnableCommit(methodMesssage.MethodBase))//判断是否授权的事务 52 { 53 TimeSpan VB_t_struct_S0 = new TimeSpan(0L);//间隔 54 using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew, VB_t_struct_S0))//事务模式 55 { 56 returnMessage = this._nextSink.SyncProcessMessage(msg); 57 Exception resultCommitException = ((IMethodReturnMessage) returnMessage).Exception;//错误信息 58 if (resultCommitException != null) 59 { 60 throw resultCommitException; 61 } 62 if (!this._biz.Rollback) 63 { 64 scope.Complete();//提交事务 65 } 66 } 67 return returnMessage; 68 } 69 returnMessage = this._nextSink.SyncProcessMessage(msg);//返回同步消息 70 Exception resultException = ((IMethodReturnMessage) returnMessage).Exception;//错误的信息 71 if (resultException != null) 72 { 73 throw resultException; 74 } 75 return returnMessage; 76 } 77 /// <summary> 78 /// 获取接收器链中的下一个消息接收器。 79 /// </summary> 80 public IMessageSink NextSink 81 { 82 get 83 { 84 return this._nextSink; 85 } 86 } 87 //System.Runtime.Remoting.Messaging.IMessageSink.NextSink 88 IMessageSink System.Runtime.Remoting.Messaging.IMessageSink.NextSink 89 { 90 get 91 { 92 return this._nextSink; 93 } 94 } 95 }
TransactionAspect继承IMessageSink处理事务消息这个是关键部分 。于通过反射取得业务层方法上所有的验证权限属性EnableCommitAttribute,并逐个进行验证。
1 [TransactionAspect]//定义事务提交的抽象类 2 public abstract class BaseBusinessComponent : ContextBoundObject 3 { 4 private bool _rollback; 5 6 protected BaseBusinessComponent() 7 { 8 } 9 //执行的状态 是否回滚 10 public bool Rollback 11 { 12 get 13 { 14 return this._rollback; 15 } 16 set 17 { 18 this._rollback = value; 19 } 20 } 21 }
定义BaseBusinessComponent抽象类 ,用于具体实现的业务类继承实现
[AttributeUsage(AttributeTargets.Method)]public sealed class EnableCommitAttribute : Attribute{}
EnableCommitAttribute继承Attribute特性,验证调用方法所需要的权限,具体的验证规则与用户信息由继承类编写。
调用处:
1 namespace demo 2 { 3 public class hous : BaseBusinessComponent//继承这个抽象基类 4 { 5 6 [EnableCommit]//加上这个就启动事务特性 7 public bool add(string w) 8 { 9 10 bool bl = false; 11 //过滤器 12 13 //业务逻辑部分省略 14 15 if (bl) 16 { 17 this.Rollback = true;//表示不提交事务,回滚 18 return false; 19 } 20 21 return true; 22 23 } 24 25 } 26 }
到此就实现了 类似 web.Match 与 Serializable 一样的特性用法只要在普通方法上加上 [EnableCommit]就实现了事务 不要事务去除即可,讲的不好请见谅。
转载于:https://www.cnblogs.com/jxluowei/p/3286056.html
把事务封装成类似Serializable用法的特性相关推荐
- 为什么要用Hibernate框架? 把SessionFactory,Session,Transcational封装成包含crud的工具类并且处理了事务,那不是用不着spring了?...
既然用Hibernate框架访问管理持久层,那为何又提到用Spring来管理以及整合Hibernate呢?把SessionFactory,Session,Transcational封装成包含crud的 ...
- imx6ull项目也是封装成脚本安装 Poky 交叉编译工具链类似ATK-STM32MP157交叉编译
[正点原子MP157连载]第六章 ATK-STM32MP157交叉编译篇 学习 2021-05-29 10:20887阅读 · 25喜欢 · 3评论 粉丝:17.3万文章:122 关注 正点原子提供了 ...
- 服务助手NSSM——将Windows程序封装成服务
文章目录 简介 安装 初试 删除服务 详细用法 服务依赖 进程优先级 关闭服务 退出和重启 I/O 文件轮换 环境变量 事件钩子 参考文献 简介 NSSM 可以将 Windows 程序封装成服务,当服 ...
- 封装成vla函数_不知道怎么封装代码?看看这几种设计模式吧!
为什么要封装代码? 我们经常听说:"写代码要有良好的封装,要高内聚,低耦合".那怎样才算良好的封装,我们为什么要封装呢?其实封装有这样几个好处: 封装好的代码,内部变量不会污染外部 ...
- 如何将自己写的verilog模块封装成IP核(二)
=======================第一篇======================= 如何将自己写的verilog模块封装成IP核 将你的设计制作成BlackBox,也就是网表文件,这样 ...
- Tools_将Python脚本封装成exe可执行文件
将Python脚本封装成exe可执行文件 将Python脚本封装成exe可执行文件 cx_freeze是用来将 Python 脚本封装成可执行程序的工具,支持最新的Python3.2版本.生成的执行文 ...
- cordova 一个将web应用程序封装成app的框架
cordova 一个将web应用程序封装成app的框架 cordova的详细介绍请参考这个链接:http://www.zhoujingen.cn/blog/7034.html 我接下来主要将如何搭建. ...
- 封装成vla函数_第四章:Python之函数
第一节:函数入门与定义函数 理解函数 所谓函数,就是为一段实现特定功能的代码"取"个名字,以后即可通过该名字来执行(调用)这段代码 从逻辑上看,函数相当于一个黑匣子 定义函数的语法 ...
- uibot在子程序执行js失败_使用 Node.js 将珍藏的 bash 脚本封装成命令行工具
阐述如何将一个常用的 bash 脚本融入 npm 生态之中,此处以最近遇到的一个 CR 提交脚本为例. 背景 作为程序猿,大家或多或少地都用过 GitHub 上的 merge request 功能.当 ...
最新文章
- Html中元素的分类
- 15条走红网络的手机摄影技巧
- [OS复习]进程互斥与同步2
- kafka一直rebalance故障,重复消费
- php 数据库 文件转移 1146 错误
- skipfish 主动扫描web安全评估工具
- Linux IPC实践(9) --System V共享内存
- 键盘出现与消失的监听方法
- Java 蓝桥杯 算法 和为T
- 从零手动实现简易Tomcat
- 分布式系统关注点(20)——阻塞与非阻塞有什么区别?
- 在终端设备上实现语音识别:ARM开源了TensorFlow预训练模型
- h5如何实现贪吃蛇小游戏
- 如何“延迟加载”嵌入式YouTube视频
- CSS中的filter与backdrop-filter属性的异同点
- 肖特基二极管焊接注意事项和判断正负极的方法
- HTPPS请求 证书 解决方案
- 我和我的中山公园”摄影作品大赛投票通道即将开启,让你的才艺C位出道~
- 软件测试|测试金字塔是什么,它的目的是什么,以及它包含哪些层次?
- android 游戏语言设置在哪里设置中文版,使命召唤手游语言变更方法 怎么设置中文...