【问题标题】:WCF Transaction Flow QuestionWCF 事务流问题
【发布时间】:2010-12-18 13:17:09
【问题描述】:

我想将 WCF 服务操作配置为在我的客户端发送一个事务时接受事务,但如果没有发送,则不创建一个事务。我认为这类似于 COM+ 中的 Supported transaction 属性。

有谁知道这是否可以通过 WCF 事务来完成?

我试图通过使用 WCF 事务编程模型(例如,服务操作上的 TransactionFlowAttribute 和 TransactionScopeRequired)而不是使用 System.Transactions 显式事务编程模型来完成这一切。

以下是我认为我希望能够做到这一点的一个例子:

ServiceA 实现调用两个数据服务的高级业务操作。服务 B 中的操作执行一次数据库更新,服务 C 中的操作执行两次数据库更新。

ServiceA ----> ServiceB ---->
|
V 服务 C ---->

ServiceC 的 2 次数据库更新需要在其根位于 ServiceC 的事务中执行。服务 B 的单个数据库更新不需要在事务中进行。但是,ServiceA 定义了一个事务,需要 ServiceB 和 ServiceC 的数据库更新两个作为原子工作单元发生。

我的问题是如何配置 ServiceB 以便在 ServiceA 调用它时加入该事务。但是,当直接调用 ServiceB 而不是通过 Service A 调用时,它不需要在事务中运行,因为它只进行一次数据库更新。

谢谢,

大卫·马德里安

【问题讨论】:

标签: wcf transactions distributed-transactions


【解决方案1】:

我认为你不能得到你想要的确切行为。

原因是一个操作必须让 TransactionScopeRequired 为真或假。所以 TransactionScopeRequired 不等同于 COM+ 事务设置。如果您希望处理事务,则 TransactionScopeRequired 必须为真。但是,这意味着该操作在调用时总是会创建一个事务。

选项 1

如果没有分布式事务,您可以做的是抑制事务:

        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete=false)]
        public string GetData(int value)
        {            
            using (TransactionScope scope = GetTransaction())
            {
                string result = DoSQL();
                scope.Complete();

                return result;
            }
        }

        private TransactionScope GetTransaction()
        {
            Transaction ambientTransaction = Transaction.Current;

            if (ambientTransaction == null 
                || 
                ambientTransaction.TransactionInformation.DistributedIdentifier.Equals(Guid.Empty))
            {
                return new TransactionScope(TransactionScopeOption.Suppress);
            }
            else
            {
                return new TransactionScope(ambientTransaction);
            }
        }

但这可能会违反您的 System.Transaction 避免要求。加上它有点气味。 :)


选项 2

我知道这不是你的问题,但为什么服务 B 不能总是使用交易?那将是我的偏好。似乎您不想要事务的开销,因为它只是一个更新调用。

我可以想到让服务 B 使用事务的 2 个原因:

  • 架构一致性——所有服务都遵循相同的模式。这使系统更易于理解,并且...
  • 可维护性——如果您的系统更易于理解,这也有助于可维护性。此外,如果稍后您需要向服务 B 添加第二次更新调用,则设计已经支持该功能,无需更改。


选项 3

另一种选择是创建 2 个 WCF 操作:一个是事务性的,一个不是。第一个可以由交易客户端调用,第二个可以在交易被认为没有必要时调用。服务本身将委托给相同的方法实现,因此不会出现代码重复。

【讨论】:

  • 感谢您的回复,但我想知道如果客户端不发送事务但加入客户端发送的事务,服务是否无法创建事务。我认为您上面描述的配置设置是 Juval Lowy 所说的“客户端\服务器”事务模式。他说这种模式“确保服务尽可能使用客户端事务,或者在客户端没有事务时使用服务端事务”。我正在寻找的是服务器使用客户端事务(如果存在)的情况,但如果没有客户端 txn,则服务器没有 txn。
猜你喜欢
  • 1970-01-01
  • 2011-01-28
  • 1970-01-01
  • 2011-09-29
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多