把事务封装成类似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的出现能否在未来取代移动应用,就目前来说,还是个未知数.一方面,用户在使用习惯上,不喜 ...
随机推荐
- 记录近期小改K-Means至MapReduce上的心得
背景: 在所有聚类算法中KMeans算是表面上最简单的一种,没有过多恼人的古希腊符号公式,没有过分繁杂的公式嵌套.对于一个初学矩阵或者仅有向量概念的非专业人士的来说,不可不畏是一把踹门利器.这个世界上 ...
- PHP添加Mssql/sqlserver2000扩展,适用于Php5.2/Php5.3/Php5.4
原文:PHP添加Mssql/sqlserver2000扩展,适用于Php5.2/Php5.3/Php5.4 本文介绍如何在Windows下配置php扩展. 本文链接 http://blog.csdn. ...
- MVC应用程序使用Web Services(asmx)
原文:MVC应用程序使用Web Services(asmx) 这次,我们练习MVC应用程序中,应用web service.先在MVC应用程序中创建一个目录Services,将用来存储Service.a ...
- <<Python基础课程>>学习笔记 | 文章13章 | 数据库支持
备注:本章介绍了比较简单,只是比较使用样品,主要假设是把握连接,利用数据库.和SQLite做演示样本 ------ Python数据库API 为了解决Python中各种数据库模块间的兼容问题,如今已经 ...
- Linux 经常使用 性能 检测 命令 说明
1.uptime [root@smgsim02 ~]# uptime 15:08:15 up 98 days, 4:19, 2 users, load average: 0.07, 0.29, ...
- C# 之 托付
托付(delegate) 托付是一种能够把引用存储为函数的类型.托付也能够看成是一种数据类型,能够用于定义变量,但它是一种特殊的数据类型,它所定义的变量能接受的数值仅仅能是一个函数,更确切的说 ...
- 逗比学树莓派之GPIO
wiringPi适合那些具有C语言基础,在接触树莓派之前已经接触过单片机或者嵌入式开发的人群.wiringPi的API函数和arduino很相似,这也使得它广受欢迎.作者给出了大量的说明 ...
- Yii中CDbCriteria常用总结
Yii的Active Recorder包装了很多. 特别是把SQL中 把where,order,limit,IN/not IN,like等常用短句都包含进CDbCriteria这个类中去,这样整个代码 ...
- 快速构建Windows 8风格应用9-竖直视图
原文:快速构建Windows 8风格应用9-竖直视图 本篇博文主要介绍竖直视图概览.关于竖直视图设计.如何构建竖直视图 竖直视图概览 Windows 8为了支持旋转的设备提供了竖屏视图,我们开发的应用 ...
- Visual Studio 单元测试之四---Generic测试
原文:Visual Studio 单元测试之四---Generic测试 这里的Generic我觉得理解为外部测试更合适.因为在这种测试模式下Visual Studio只是启动一个外部的程序,然后通过返 ...