把事务封装成类似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用法的特性的更多相关文章

  1. 将自己写的组件封装成类似element-ui一样的库,可以cdn引入

    在写好自己的组件之后 第一步 修改目录结构 在根目录下创建package文件夹,用于存放你要封装的组件 第二部 在webpack配置中加入 pages与publicpath同级 pages: { in ...

  2. 为什么要用Hibernate框架? 把SessionFactory,Session,Transcational封装成包含crud的工具类并且处理了事务,那不是用不着spring了?

    既然用Hibernate框架访问管理持久层,那为何又提到用Spring来管理以及整合Hibernate呢?把SessionFactory,Session,Transcational封装成包含crud的 ...

  3. OracleHelper(对增删改查分页查询操作进行了面向对象的封装,对批量增删改操作的事务封装)

    公司的一个新项目使用ASP.NET MVC开发,经理让我写个OracleHelper,我从网上找了一个比较全的OracleHelper类,缺点是查询的时候返回DataSet,数据增删改要写很多代码(当 ...

  4. 将Python脚本封装成exe可执行文件 转

    将Python脚本封装成exe可执行文件 http://www.cnblogs.com/renzo/archive/2012/01/01/2309260.html  cx_freeze是用来将 Pyt ...

  5. 如何将自己写的verilog模块封装成IP核

    如何将自己写的verilog模块封装成IP核 (2014-11-21 14:53:29) 转载▼ 标签: 财经 分类: 我的东东 =======================第一篇========= ...

  6. 封装一个类似jquery的ajax方法

    //封装一个类似jquery的ajax方法,当传入参数,就可以发送ajax请求 //参数格式如下{ // type:"get"/"post", // dataT ...

  7. .NET 同步与异步之封装成Task(五)

    本随笔续接:.NET 实现并行的几种方式(四) 前篇随笔已经介绍了几种可以实现并发的方式,其中异步方法.是最简便的方式.而 异步方式是基于 Task 和 async修饰符和await运算符实现的. 换 ...

  8. 将HTML5封装成android应用APK文件的几种方法

    越来越多的开发者热衷于使用html5+JavaScript开发移动Web App.不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数.一方面,用户在使用习惯上,不喜 ...

  9. 将HTML5封装成android应用APK文件的几种方法(转载)

    越来越多的开发者热衷于使用html5+JavaScript开发移动Web App.不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数.一方面,用户在使用习惯上,不喜 ...

随机推荐

  1. 记录近期小改K-Means至MapReduce上的心得

    背景: 在所有聚类算法中KMeans算是表面上最简单的一种,没有过多恼人的古希腊符号公式,没有过分繁杂的公式嵌套.对于一个初学矩阵或者仅有向量概念的非专业人士的来说,不可不畏是一把踹门利器.这个世界上 ...

  2. PHP添加Mssql/sqlserver2000扩展,适用于Php5.2/Php5.3/Php5.4

    原文:PHP添加Mssql/sqlserver2000扩展,适用于Php5.2/Php5.3/Php5.4 本文介绍如何在Windows下配置php扩展. 本文链接 http://blog.csdn. ...

  3. MVC应用程序使用Web Services(asmx)

    原文:MVC应用程序使用Web Services(asmx) 这次,我们练习MVC应用程序中,应用web service.先在MVC应用程序中创建一个目录Services,将用来存储Service.a ...

  4. &lt;&lt;Python基础课程&gt;&gt;学习笔记 | 文章13章 | 数据库支持

    备注:本章介绍了比较简单,只是比较使用样品,主要假设是把握连接,利用数据库.和SQLite做演示样本 ------ Python数据库API 为了解决Python中各种数据库模块间的兼容问题,如今已经 ...

  5. Linux 经常使用 性能 检测 命令 说明

    1.uptime [root@smgsim02 ~]# uptime  15:08:15 up 98 days,  4:19,  2 users,  load average: 0.07, 0.29, ...

  6. C# 之 托付

    托付(delegate)     托付是一种能够把引用存储为函数的类型.托付也能够看成是一种数据类型,能够用于定义变量,但它是一种特殊的数据类型,它所定义的变量能接受的数值仅仅能是一个函数,更确切的说 ...

  7. 逗比学树莓派之GPIO

           wiringPi适合那些具有C语言基础,在接触树莓派之前已经接触过单片机或者嵌入式开发的人群.wiringPi的API函数和arduino很相似,这也使得它广受欢迎.作者给出了大量的说明 ...

  8. Yii中CDbCriteria常用总结

    Yii的Active Recorder包装了很多. 特别是把SQL中 把where,order,limit,IN/not IN,like等常用短句都包含进CDbCriteria这个类中去,这样整个代码 ...

  9. 快速构建Windows 8风格应用9-竖直视图

    原文:快速构建Windows 8风格应用9-竖直视图 本篇博文主要介绍竖直视图概览.关于竖直视图设计.如何构建竖直视图 竖直视图概览 Windows 8为了支持旋转的设备提供了竖屏视图,我们开发的应用 ...

  10. Visual Studio 单元测试之四---Generic测试

    原文:Visual Studio 单元测试之四---Generic测试 这里的Generic我觉得理解为外部测试更合适.因为在这种测试模式下Visual Studio只是启动一个外部的程序,然后通过返 ...