把事务封装成类似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的出现能否在未来取代移动应用,就目前来说,还是个未知数.一方面,用户在使用习惯上,不喜 ...
随机推荐
- RPC框架
RPC框架实现 - 路由控制篇 2015-04-27 22:26 by bangerlee, 499 阅读, 1 评论, 收藏, 编辑 RPC(Remote Procedure Call,远程过程调用 ...
- cocos2dx 3.0正式版 于mac在新建项目
下载cocos2dx 3.0正式版,和安装python2.7.*版本号. 加入cocos命令: mac下: 在cocos2d-x\tools\cocos2d-console\bin文件夹下.执行ins ...
- bootstrap collapse MVC .net漂亮的折叠List
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta na ...
- webkit的几个属性
-webkit-text-size-adjust 1.当样式表里font-size<12px时,中文版chrome浏览器里字体显示仍为12px,这时可以用 html{-webkit-text-s ...
- CodeSmith
完美解决CodeSmith无法获取MySQL表及列Description说明注释的方案 问题描述: CodeSmith是现在比较实用的代码生成器,但是我们发现一个问题: 使用CodeSmith编写 ...
- C++在struct与class差异
在C++中,既能够用structkeyword进行类的定义,也能够用classkeyword进行类的定义,那么这两者究竟有什么差别呢? 唯一的一点差别是:struct和class的默认訪问权限不一样. ...
- 安装Oracle 9i - 初学者系列 - 学习者系列文章
Oracle 9i数据库是经典的Oracle版本,就象SQL Server 2000一样.笔者最初使用到的Oracle版本就是Oracle 9i.下面就介绍下Oracle 9i的安装. 1. 下载O ...
- C语言JSON-RPC
近期对json-rpc比較感兴趣,思想非常easy,并且看到了非常多不同语言的实现.在github上 hmngomes 的 json-rpc-c (实现的是server端,基于TCP流),短 ...
- android shape总结 和控制的风格定制
1:shape总结 1):shape文件是放置在drawable文件下的.res/drawable/filename.xml. 2):shape类型:android:shape. 一共同拥有四种:re ...
- A/B测试评测
A/B测试评测 A/B测试在各类网站设计中已经是比较常见的,本文着重讲讲A/B测试在应用推送领域的作用. 目前国外开通A/B测试的推送服务商只有swrve,而国内的个推也在前不久发布的smart pu ...