我希望将WCF服务操作配置为在我的客户端发送一个事务时接受事务,但如果没有发送则不创建一个事务。我认为这与COM +中的Supported transaction属性类似。
有谁知道这是否可以通过WCF交易完成?
我试图通过使用WCF事务编程模型(例如,服务操作上的TransactionFlowAttribute和TransactionScopeRequired)而不是使用System.Transactions显式事务编程模型来实现这一切。
以下是我希望能够做到这一点的原因示例:
ServiceA实现了一个调用两个数据服务的高级业务操作。服务B中的操作执行单个数据库更新,而服务C中的操作执行两个数据库更新。
ServiceA ----> ServiceB ----> < 1 DB update>
|
V Service C ----> < 2 DB更新>
ServiceC的2个数据库更新需要在ServiceCl的根目录下执行。服务B的单个数据库更新不需要在事务中进行。但是,ServiceA定义了一个事务,该事务需要ServiceB和ServiceC的数据库更新两个作为原子工作单元发生。
我的问题是如何配置ServiceB,以便在ServiceA调用它时,它会在该事务中登记。但是,当直接调用ServiceB而不是通过服务A调用ServiceB时,它不需要在事务中运行,因为它只执行一次数据库更新。
谢谢,
David Madrian
答案 0 :(得分:2)
我认为你不能得到你想要的确切行为。
原因是一个Operation必须要么TransactionScopeRequired为true或false。因此TransactionScopeRequired不等同于COM +事务设置。如果您希望流动事务,则TransactionScopeRequired必须为true。但是,这意味着操作将始终在调用时创建事务。
如果没有分布式事务,你可以做的是压制事务:
[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避免要求。再加上它有点味道。 :)
我知道这不是你的问题,但为什么服务B不能总是使用交易?那是我的偏好。看起来你不想要交易的开销,因为它只是一次更新调用。
我可以想到服务B使用交易的两个理由:
另一个选择是创建2个WCF操作:一个是事务性的,另一个不是。第一个可以由事务客户端调用,第二个可以在认为不需要事务时调用。服务本身将委托给相同的方法实现,因此不会有代码重复。