把事务封装成类似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. RPC框架

    RPC框架实现 - 路由控制篇 2015-04-27 22:26 by bangerlee, 499 阅读, 1 评论, 收藏, 编辑 RPC(Remote Procedure Call,远程过程调用 ...

  2. cocos2dx 3.0正式版 于mac在新建项目

    下载cocos2dx 3.0正式版,和安装python2.7.*版本号. 加入cocos命令: mac下: 在cocos2d-x\tools\cocos2d-console\bin文件夹下.执行ins ...

  3. bootstrap collapse MVC .net漂亮的折叠List

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta na ...

  4. webkit的几个属性

    -webkit-text-size-adjust 1.当样式表里font-size<12px时,中文版chrome浏览器里字体显示仍为12px,这时可以用 html{-webkit-text-s ...

  5. CodeSmith

    完美解决CodeSmith无法获取MySQL表及列Description说明注释的方案   问题描述: CodeSmith是现在比较实用的代码生成器,但是我们发现一个问题: 使用CodeSmith编写 ...

  6. C++在struct与class差异

    在C++中,既能够用structkeyword进行类的定义,也能够用classkeyword进行类的定义,那么这两者究竟有什么差别呢? 唯一的一点差别是:struct和class的默认訪问权限不一样. ...

  7. 安装Oracle 9i - 初学者系列 - 学习者系列文章

    Oracle 9i数据库是经典的Oracle版本,就象SQL Server 2000一样.笔者最初使用到的Oracle版本就是Oracle 9i.下面就介绍下Oracle 9i的安装. 1.  下载O ...

  8. C语言JSON-RPC

         近期对json-rpc比較感兴趣,思想非常easy,并且看到了非常多不同语言的实现.在github上 hmngomes 的 json-rpc-c (实现的是server端,基于TCP流),短 ...

  9. android shape总结 和控制的风格定制

    1:shape总结 1):shape文件是放置在drawable文件下的.res/drawable/filename.xml. 2):shape类型:android:shape. 一共同拥有四种:re ...

  10. A/B测试评测

    A/B测试评测 A/B测试在各类网站设计中已经是比较常见的,本文着重讲讲A/B测试在应用推送领域的作用. 目前国外开通A/B测试的推送服务商只有swrve,而国内的个推也在前不久发布的smart pu ...