/// <summary>
 ///     创建一个新的网络事务
 /// </summary>
 /// <param name="appName">目标APP的名称</param>
 /// <param name="target">标示网络终点接的协议簇组合</param>
 /// <param name="maximumRspTime">等待当前网络事务RSP消息的最大时间</param>
 /// <param name="resourceUri">KAE资源URI</param>
 /// <param name="balanceFlag">负载标识</param>
 /// <param name="communicationType">通信方式</param>
 /// <param name="version">
 ///     目标APP的版本
 ///     <para>* 默认为: latest</para>
 /// </param>
 /// <param name="protocolSelf">
 ///     使用的协议栈的角色
 ///     <para>* 如果当前事务代理器所承载的消息协议为MetadataContainer时请忽略此参数</para>
 /// </param>
 /// <returns>返回新的事务</returns>
 public IMessageTransaction <TMessage> CreateTransaction(string appName, Protocols target, TimeSpan maximumRspTime, Guid balanceFlag, string version = "latest", KAEResourceUri resourceUri = null, NetworkCommunicationTypes communicationType = NetworkCommunicationTypes.Dulplex, string protocolSelf = null)
 {
     return(CreateTransaction(appName, target, maximumRspTime, balanceFlag.GetHashCode(), version, resourceUri, communicationType, protocolSelf));
 }
 /// <summary>
 ///     创建一个新的网络事务
 /// </summary>
 /// <param name="appName">目标APP的名称</param>
 /// <param name="target">标示网络终点接的协议簇组合</param>
 /// <param name="version">
 ///     目标APP的版本
 ///     <para>* 默认为: latest</para>
 /// </param>
 /// <param name="resourceUri">KAE资源URI</param>
 /// <param name="communicationType">通信方式</param>
 /// <param name="protocolSelf">
 ///     使用的协议栈的角色
 ///     <para>* 如果当前事务代理器所承载的消息协议为MetadataContainer时请忽略此参数</para>
 /// </param>
 /// <returns>返回新的事务</returns>
 public IMessageTransaction <TMessage> CreateTransaction(string appName, Protocols target, string version = "latest", KAEResourceUri resourceUri = null, NetworkCommunicationTypes communicationType = NetworkCommunicationTypes.Dulplex, string protocolSelf = null)
 {
     return(CreateTransaction(appName, target, TransactionGlobal.TransactionTimeout, version, resourceUri, communicationType, protocolSelf));
 }
        /// <summary>
        ///     创建一个新的网络事务
        /// </summary>
        /// <param name="appName">目标APP的名称</param>
        /// <param name="target">标示网络终点接的协议簇组合</param>
        /// <param name="maximumRspTime">等待当前网络事务RSP消息的最大时间</param>
        /// <param name="resourceUri">KAE资源URI</param>
        /// <param name="balanceFlag">负载标识</param>
        /// <param name="communicationType">通信方式</param>
        /// <param name="version">
        ///     目标APP的版本
        ///     <para>* 默认为: latest</para>
        /// </param>
        /// <param name="protocolSelf">
        ///     使用的协议栈的角色
        ///     <para>* 如果当前事务代理器所承载的消息协议为MetadataContainer时请忽略此参数</para>
        /// </param>
        /// <returns>返回新的事务</returns>
        public IMessageTransaction <TMessage> CreateTransaction(string appName, Protocols target, TimeSpan maximumRspTime, long balanceFlag, string version = "latest", KAEResourceUri resourceUri = null, NetworkCommunicationTypes communicationType = NetworkCommunicationTypes.Dulplex, string protocolSelf = null)
        {
            if (string.IsNullOrEmpty(appName))
            {
                throw new ArgumentNullException("appName");
            }
            string           errMsg;
            ApplicationLevel level = (resourceUri == null ? ApplicationLevel.Stable : _callback(resourceUri));
            KAERingNode      ringNode;
            IServerConnectionAgent <TMessage> agent = _cluster.GetChannel(target, level, _container.GetDefaultProtocolStack(_cluster.ProtocolType), balanceFlag, out errMsg, out ringNode);

            if (agent == null)
            {
                lock (_lockObj)
                {
                    //try to obtains agent object again for ensuring that the newest remoting addresses can be appliy in the multiple threading env.
                    agent = _cluster.GetChannel(target, level, _container.GetDefaultProtocolStack(_cluster.ProtocolType), balanceFlag, out errMsg, out ringNode);
                    if (agent == null && !GetMissedRemoteAddresses(appName, version, target, level))
                    {
                        return(new FailMessageTransaction <TMessage>(errMsg));
                    }
                    agent = _cluster.GetChannel(target, level, _container.GetDefaultProtocolStack(_cluster.ProtocolType), balanceFlag, out errMsg, out ringNode);
                    //check returned value again for avoiding couldnt connect to the remote address now.
                    if (agent == null)
                    {
                        return(new FailMessageTransaction <TMessage>(errMsg));
                    }
                }
            }
            MessageTransaction <TMessage> transaction = NewTransaction(new Lease(DateTime.Now.Add(maximumRspTime)), agent.GetChannel());

            transaction.SetMessageIdentity(new MessageIdentity {
                ProtocolId = (byte)target.ProtocolId, ServiceId = (byte)target.ServiceId, DetailsId = (byte)target.DetailsId
            });
            transaction.TransactionManager = _transactionManager;
            transaction.Identity           = (communicationType == NetworkCommunicationTypes.Dulplex ? IdentityHelper.Create(agent.GetChannel().LocalEndPoint, TransportChannelTypes.TCP) : IdentityHelper.CreateOneway(agent.GetChannel().LocalEndPoint, TransportChannelTypes.TCP));
            transaction.KPPUniqueId        = ringNode.KPPUniqueId;
            return(_transactionManager.Add(transaction.Identity, transaction) ? transaction : null);
        }