gpt4 book ai didi

wcf - 如何使用 CoreService 在自定义类上实现 WCF 事务支持?

转载 作者:行者123 更新时间:2023-12-01 22:00:34 24 4
gpt4 key购买 nike

我编写了一个类来帮助使用核心服务向发布目标添加和删除目的地。目的地通常通过核心服务公开为字符串(带有 XML 内容),因此我围绕它编写了自己的包装器,等等。

我现在遇到的情况是,我需要更新 2 个发布目标,并且认为使用事务范围来确保两个目标同时更新会很酷。

然而,我正在努力实现这一点。

代码工作(使用标准 CoreService WCF 客户端):

TransactionOptions txOptions = new TransactionOptions 
{ IsolationLevel = IsolationLevel.ReadCommitted };
using(TransactionScope scope = new TransactionScope(
TransactionScopeOption.Required, txOptions))
{
PublicationTargetData publicationTarget1 = (PublicationTargetData)client.Read("tcm:0-1-65537", readOptions);
PublicationTargetData publicationTarget2 = (PublicationTargetData)client.Read("tcm:0-2-65537", readOptions);

publicationTarget1.TargetLanguage = "JSP";
publicationTarget2.TargetLanguage = "JSP";
client.Save(publicationTarget1, readOptions);
client.Save(publicationTarget2, readOptions);

// Stop saving
scope.Dispose();
}

执行此代码将成功回滚我所做的更改(如果我在 scope.Dispose() 之前中断并检查 Tridion 中的发布目标,它会成功更改目标,然后“撤消”改变)。

如果我现在尝试在事务中使用我的“扩展发布目标”类,我将无法处置它。

TransactionOptions options = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted };
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, options))
{
ExtendedPublicationTarget target1 = new ExtendedPublicationTarget("tcm:0-1-65537");
ExtendedPublicationTarget target2 = new ExtendedPublicationTarget("tcm:0-2-65537");
target1.Destinations.Add(target1.Destinations[0]);
target2.Destinations.Add(target2.Destinations[0]);
target1.Save();
target2.Save();
scope.Dispose();
}

基本上,这就是问题:我必须做什么才能将事务性添加到我的 .Save() 方法中?

我尝试过这样做:

[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
public void Save()
{
_client.Save(targetData, readOptions);
}

但这并没有什么区别。有没有办法确定我当前是否处于交易中并以某种方式“使用”该交易?我不想要求进行交易,只是想选择在其中进行操作。

谢谢,对这么长的帖子感到抱歉...想确保我提供了尽可能多的信息。

最佳答案

最好的资源是:WCF Transaction Propagation

您至少缺少一个步骤。您还需要在绑定(bind)中启用事务:

<bindings>
<netTcpBinding>
<binding name = “TransactionalTCP” transactionFlow = “true” />
</netTcpBinding>
</bindings>

Is there a way to determine if I am currently in a transaction and somehow "use" that transaction?

是的。要确定您是否处于交易中,您可以检查 Transaction.Current。如果您正在进行交易,除非您明确选择退出,否则您将使用它。这就是环境事务的美丽/可怕之处。

WCF Transaction Propagation 中的图 5 :

class MyService : IMyContract 
{
[OperationBehavior(TransactionScopeRequired = true)]
public void MyMethod(...)
{
Transaction transaction = Transaction.Current;
Debug.Assert(transaction.TransactionInformation.
DistributedIdentifier != Guid.Empty);
}
}

如果 Transaction.Current.TransactionInformation.DistributedIdentifier 为空,则事务是本地的并且没有“流动”。请注意,在 TransactionFlowOptions.Allowed 配置中,如果事务无法流动,它会默默地失败。所以这确实是检查的唯一方法......并且不流动的情况比您想象的更容易发生。

当我在生产服务中使用事务时,我实际上避免了 TransactionFlowOptions.Allowed 因为调用者永远不确定事务是否真正流动。如果部署中存在绑定(bind)配置错误,一切都会运行良好,但回滚会失败......这是一个非常容易检测到的错误。所以我切换到必需的。然后调用者可以确保他们提供的交易实际上已成功传递。 (如果交易未在 TransactionFlowOptions.Required 配置中流动,您将收到异常。)

关于wcf - 如何使用 CoreService 在自定义类上实现 WCF 事务支持?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12398027/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com