国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

利用AOP寫2PC框架(二)

2019-11-17 02:50:31
字體:
來源:轉載
供稿:網友

利用AOP寫2PC框架(二)

AOP的底層已經封裝好了以后,我們就要開始針對應用層寫具體的業務邏輯了。

也就是說我們需要有個類繼承于AopPRoxyBase,并且重寫其After,Bofore以達到我們的攔截記錄的功能。代碼如下:

public class TransactionProxy : AopProxyBase    {        public TransactionProxy(MarshalByRefObject obj, Type type)            : base(obj, type)        { }        public override void Before(System.Runtime.Remoting.Messaging.IMessage requestMsg, AopMethodAttribute[] attrs)        {        }        public override void After(System.Runtime.Remoting.Messaging.IMessage requestMsg, System.Runtime.Remoting.Messaging.IMessage Respond, AopMethodAttribute[] attrs)        {            foreach (var attr in attrs)            {                if (attr is LogicRollBackTransAttribute)                {                    return;                }            }            var args = requestMsg.Properties["__Args"] as object[];            string methodName = requestMsg.Properties["__MethodName"] as string;            CustomTransaction customTrans = null;            List<object> list = new List<object>();            customTrans = CallContext.GetData(TransKey.CustomTransKey) as CustomTransaction;            if (customTrans != null)            {                list.AddRange(args);                TransactionUnit unit = APPTransactionManage.Instance.GetRollBackInfo(methodName);                if (unit != null)                {                    unit.Argments = list;                    unit.Mark = customTrans.Mark;                }                customTrans.Compensation.Add(unit);                TransQueueManage.Instance.Push                (                    new Model.BankTransLog                    {                        Mark = unit.Mark,                        MethodName = methodName,                        ParamsConfig = JsonHelper.ToJson(unit.Argments),                        Status = 0,                        Type = 0                    }                );                CallContext.SetData(TransKey.CustomTransKey, customTrans);                var outArgs = Respond.Properties["__OutArgs"] as object[];                IDbTransaction dbTrans;                foreach (var attr in attrs)                {                    if (attr is DbTransAttribute || attr is LogicTransAttribute)                    {                        if (outArgs != null)                        {                            foreach (var arg in outArgs)                            {                                if (arg is IDbTransaction)                                {                                    dbTrans = arg as IDbTransaction;                                    if (customTrans != null)                                    {                                        customTrans.AddDbTransaction(dbTrans);                                    }                                }                            }                        }                    }                }            }        }    }
View Code

在After的地方,我們可以看到,我們做了一次LogicRollBackTransAttribute的判定,避免在回調的時候,又再走一次攔截和記錄的流程。

同時做了DbTransAttribute和LogicTransAttribute的判定。因為我把事務分為兩類,一類是db本身自己控制的,可以直接rollback的,一類是logic的,需要我們去手動通過邏輯回滾的。代碼如下:

[AttributeUsage(AttributeTargets.Method)]    public class LogicTransAttribute : AopMethodAttribute    {        public string MethodName { get; set; }        public LogicTransAttribute()        {        }        public LogicTransAttribute(string name)        {            this.MethodName = name;        }    }[AttributeUsage(AttributeTargets.Method)]    public class DbTransAttribute : AopMethodAttribute    {            }
View Code

同時可以看到,我把每一個函數的調用作為一個單元,用TransactionUnit類來保存,代碼如下:

public class TransactionUnit    {        public object InstanceObject;        /// <summary>        /// 執行的方法        /// </summary>        public MethodInfo Forward;        /// <summary>        /// 失敗回滾的方法        /// </summary>        public MethodInfo Rollback;        /// <summary>        /// 參數        /// </summary>        public IList<object> Argments;        /// <summary>        /// 唯一標識        /// </summary>        public string Mark;    }
View Code

因為,一個事務里面,可能包含了多次操作redis,或者多次操作db,為了保證線程安全,同時又需要避開鎖,我用了CallContext將一個線程里面的一段事務,保存在其線程上下文中。在保存一個完整的TransactionUnit的時候,不可能每一次都去通過反射去取MethodInfo,所以又增加了一段初始化和字典來保存其MethodInfo。代碼如下:

public class AppTransactionManage    {        private Dictionary<string, TransactionUnit> _transMaps;        static AppTransactionManage() { }        private AppTransactionManage()        {            if (this._transMaps == null)            {                this._transMaps = new Dictionary<string, TransactionUnit>();            }        }        private static AppTransactionManage _instance;        public static AppTransactionManage Instance        {            get            {                if (_instance == null)                {                    _instance = new AppTransactionManage();                }                return _instance;            }        }        public TransactionUnit GetRollBackInfo(string methodName)        {            if (this._transMaps == null) throw new ArgumentNullException("not init");            if (this._transMaps.ContainsKey(methodName))            {                return this._transMaps[methodName];            }            return null;        }        public void Init(params string[] assembly)        {            this.Init(2, assembly);        }        public void Init(int threadNum, params string[] assembly)        {            if (assembly != null)            {                foreach (string s in assembly)                {                    var ass = Assembly.Load(s);                    if (ass != null)                    {                        var types = ass.GetTypes();                        foreach (var type in types)                        {                            var transAttr = type.GetCustomAttribute(typeof(TransactionAttribute), false) as TransactionAttribute;                            if (transAttr != null)                            {                                var methods = type.GetMethods();                                foreach (var method in methods)                                {                                    var forwardTrans = method.GetCustomAttribute(typeof(LogicTransAttribute), false) as LogicTransAttribute;                                    var rollbackTrans = method.GetCustomAttribute(typeof(LogicRollBackTransAttribute), false) as LogicRollBackTransAttribute;
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 蒙自县| 太保市| 惠安县| 德清县| 永修县| 焦作市| 大兴区| 五峰| 图木舒克市| 皋兰县| 胶州市| 唐河县| 禹州市| 和林格尔县| 威宁| 沅陵县| 卢氏县| 和田县| 怀集县| 朝阳市| 平顶山市| 西青区| 四子王旗| 兴山县| 隆昌县| 富平县| 循化| 潞西市| 关岭| 达拉特旗| 康定县| 栾川县| 诸城市| 巍山| 鄂州市| 清涧县| 洛川县| 嵩明县| 永靖县| 长春市| 闻喜县|