把事务封装成类似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]就实现了事务 不要事务去除即可,讲的不好请见谅。
把事务封装成类似Serializable用法的特性的更多相关文章
- 将自己写的组件封装成类似element-ui一样的库,可以cdn引入
在写好自己的组件之后 第一步 修改目录结构 在根目录下创建package文件夹,用于存放你要封装的组件 第二部 在webpack配置中加入 pages与publicpath同级 pages: { in ...
- 为什么要用Hibernate框架? 把SessionFactory,Session,Transcational封装成包含crud的工具类并且处理了事务,那不是用不着spring了?
既然用Hibernate框架访问管理持久层,那为何又提到用Spring来管理以及整合Hibernate呢?把SessionFactory,Session,Transcational封装成包含crud的 ...
- OracleHelper(对增删改查分页查询操作进行了面向对象的封装,对批量增删改操作的事务封装)
公司的一个新项目使用ASP.NET MVC开发,经理让我写个OracleHelper,我从网上找了一个比较全的OracleHelper类,缺点是查询的时候返回DataSet,数据增删改要写很多代码(当 ...
- 将Python脚本封装成exe可执行文件 转
将Python脚本封装成exe可执行文件 http://www.cnblogs.com/renzo/archive/2012/01/01/2309260.html cx_freeze是用来将 Pyt ...
- 如何将自己写的verilog模块封装成IP核
如何将自己写的verilog模块封装成IP核 (2014-11-21 14:53:29) 转载▼ 标签: 财经 分类: 我的东东 =======================第一篇========= ...
- 封装一个类似jquery的ajax方法
//封装一个类似jquery的ajax方法,当传入参数,就可以发送ajax请求 //参数格式如下{ // type:"get"/"post", // dataT ...
- .NET 同步与异步之封装成Task(五)
本随笔续接:.NET 实现并行的几种方式(四) 前篇随笔已经介绍了几种可以实现并发的方式,其中异步方法.是最简便的方式.而 异步方式是基于 Task 和 async修饰符和await运算符实现的. 换 ...
- 将HTML5封装成android应用APK文件的几种方法
越来越多的开发者热衷于使用html5+JavaScript开发移动Web App.不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数.一方面,用户在使用习惯上,不喜 ...
- 将HTML5封装成android应用APK文件的几种方法(转载)
越来越多的开发者热衷于使用html5+JavaScript开发移动Web App.不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数.一方面,用户在使用习惯上,不喜 ...
随机推荐
- 突破IP限制动态替换代理ip。
须要导入的两个jar包 实现的javabean <span style="font-size:18px;">package com.jx.po; public clas ...
- The Swift Programming Language-官方教程精译Swift(6)控制流--Control Flow
Swift提供了类似C语言的流程控制结构,包括可以多次执行任务的for和while循环,基于特定条件选择执行不同代码分支的if和switch语句,还有控制流程跳转到其他代码的break和continu ...
- 基于HTTP/2和protobuf的RPC框架:GRPC
谷歌发布的首款基于HTTP/2和protobuf的RPC框架:GRPC Google 刚刚开源了grpc, 一个基于HTTP2 和 Protobuf 的高性能.开源.通用的RPC框架.Protobu ...
- 【翻译自mos文章】SYS_OP_C2C 导致的全表扫描(fts)/全索引扫描
SYS_OP_C2C 导致的全表扫描(fts)/全索引扫描 參考原文: SYS_OP_C2C Causing Full Table/Index Scans (Doc ID 732666.1) 适用于: ...
- Linux httpd 跳转简单方法二
使用mod_proxy 这种方法要添加上mod_proxy_http.so 在httpd.conf 中打开httpd-vhost 在 httpd-vhost 里面添加上 <VirtualHost ...
- struts2文件下载 <result type="stream">
<!--struts.xml配置--> <action name="download" class="com.unmi.action.DownloadA ...
- NGUI ScrollView动态加入和删除对象。
动态加入,基本思想是: 1.先把要加入的元素在编辑器中编辑好,制作成一个prefab. 2.在代码中,动态的生成一个新的对象增加到Grid对象的子对象中.这里利用到了Resources对象,这个对象的 ...
- Git基础教程
Git是一个分布式的版本控制工具,本篇文章从介绍Git开始,重点在于介绍Git的基本命令和使用技巧,让你尝试使用Git的同时,体验到原来一个版 本控制工具可以对开发产生如此之多的影响,文章分为两部分, ...
- appium之java API(2)
TouchAction AppiumDriver的辅助类,主要针对手势操作,比方滑动.长按.拖动等.TouchAction的原理是讲一系列的动作放在一个链条中,然后将该链条传递给server.serv ...
- SQL点滴16—SQL分页语句总结
原文:SQL点滴16-SQL分页语句总结 今天对分页语句做一个简单的总结,他们大同小异的,只要理解其中一个其他的就很好理解了. 使用top选项 *from Orders orderid from Or ...