⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mixtransactionsink.cs

📁 该文件是多层体系结构的数据访问层
💻 CS
字号:
#region Copyright & License
//
// $Copyright:$
//
#endregion
#region Document Information
// $Author: Bai.shijun $
// $Rev: $ 
// $Date: 05-10-08 16:13 $
#endregion

using System;
using System.Collections;
using System.Runtime.Remoting.Messaging;
using System.EnterpriseServices;

namespace Eai.Data.Transaction
{
    internal class MixTransactionSink : IMessageSink
    {
        private Type activatorType;
        private MixTransactionOption mixTransOption;

        public MixTransactionSink(IMessageSink nextSink, Type activatorType, MixTransactionOption mixTransOption)
        {
            this.activatorType = activatorType;
            this.mixTransOption = mixTransOption;
            this.nextSink = nextSink;
        }

        #region IMessageSink Members

        IMessageSink nextSink;
        public IMessageSink NextSink
        {
            get
            {
                return nextSink;
            }
        }

        public IMessage SyncProcessMessage(IMessage msg)
        {
            TransactionManager transManager = TransactionManager.Instance;
            IMixTransaction trans = null;

            IMethodCallMessage methodMessage = msg as IMethodCallMessage;
            if (methodMessage != null)
            {
                if (IsTransactionMethod(methodMessage))
                {
                    TransactionAttribute transAttr = GetTransactionOption(activatorType);
                    TransactionOption transOption;
                    transOption = transAttr.Value;
                    if (mixTransOption != MixTransactionOption.NotSupported)
                    {
                        switch (transOption)
                        {
                            case TransactionOption.Required:
                                {
                                    if (!transManager.IsInTransaction)
                                    {
                                        trans = CreateTransaction(mixTransOption, transAttr);
                                        transManager.Push(trans);
                                    }
                                    break;
                                }
                            case TransactionOption.RequiresNew:
                                {
                                    trans = CreateTransaction(mixTransOption, transAttr);
                                    if (!trans.SupportParallelTransactin)
                                    {
                                        // do as Require mode.
                                        if (!transManager.IsInTransaction)
                                        {
                                            trans = CreateTransaction(mixTransOption, transAttr);
                                            transManager.Push(trans);
                                        }
                                        //throw new InvalidOperationException(
                                        //    String.Format("this mix transaction manager doesn't support parallel transactin, so it can not use in RequireNew mode.({0})", trans.GetType()));
                                    }
                                    else
                                    {
                                        transManager.Push(trans);
                                    }
                                    break;
                                }
                            default:
                                {
                                    break;
                                }
                        }
                    }
                }
            }

            if (trans != null)
            {
                trans.Begin();
            }

            //This calls the object:
            IMessage callMessage = nextSink.SyncProcessMessage(msg);

            if (trans != null)
            {
                ReturnMessage returnedMessage = callMessage as ReturnMessage;
                if (returnedMessage != null && returnedMessage.Exception != null)
                {
                    // if exception, rollback.
                    trans.Rollback();
                }
                else
                {
                    trans.Commit();
                }

                transManager.Pop();
            }

            return callMessage;
        }

        private IMixTransaction CreateTransaction(MixTransactionOption mixTransOption, TransactionAttribute transAttr)
        {
            IMixTransaction trans = TransactionManager.CreateTransaction(mixTransOption, transAttr);
            return trans;
        }

        private bool IsTransactionMethod(IMethodCallMessage msg)
        {
            // 如果方法override并且定义不一致,则不能读出正确的定义。
            // 通常情况下override的业务方法,事务是一致的。
            System.Reflection.MethodInfo method = activatorType.GetMethod(msg.MethodName);
            if (method == null) return false;
            object[] objs = method.GetCustomAttributes(typeof(AutoCompleteAttribute), true);
            if (objs.Length != 1)
            {
                return false;
            }
            return true;
        }

        private static Hashtable transactionDefines = new Hashtable();
        private TransactionAttribute GetTransactionOption(Type classType)
        {
            TransactionAttribute transAttr = new TransactionAttribute();

            object obj = transactionDefines[classType.FullName];
            if (obj != null)
            {
                transAttr = (TransactionAttribute)(obj);
            }
            else
            {
                // get dtc transactopn option
                object[] objs = classType.GetCustomAttributes(typeof(TransactionAttribute), true);
                if (objs.Length != 0)
                {
                    transAttr = objs[0] as TransactionAttribute;
                }

                transactionDefines.Add(classType.FullName, transAttr);
            }

            return transAttr;
        }

        public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
        {
            return nextSink.AsyncProcessMessage(msg, replySink);
        }

        #endregion
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -