这是我的第一个WCF客户端和服务器端。 SQL server 2008。
我被迫在我的Windows窗体应用程序中使用TransactionScope事务,该应用程序作为客户端针对WCF服务运行。我之前没有使用过这种类型的交易,通常使用我喜欢的connection.BeginTransaction(),因为它更容易理解正在发生的事情。
我调用了一个函数(我希望嵌套事务),但是我创建一个新的TransactionScope实例的一个调用是在#34;事务已中止"例外。 内部异常为空。 我假设交易在此之前已经回滚,但我不知道如何跟踪是否有正在进行的环境事务以及状态是什么。
示例客户端(不是真正的代码。我检查过所有的func都在使用scope.Commit()) 有关如何追踪问题的任何帮助吗?
(我经常会收到有关必须启动MSDTC服务的错误消息,但我不知道为什么在使用单一数据库/ wcf服务时使用分布式服务器<) / p>
void Function1(AMessageObj m)
{
using (var client = GetOpenWebClient())
WriteMessage(m, client);
}
void WriteMessage(AMessage m, OpenWebClient client)
{
using (var scope = new TransactionScope())
{
var audit = GetSomeAuditInfo(AMessage.UserId, client);
WriteTheMessage(AMessage, client);
WriteAudit(audit, client);
client.SetTime(DateTime.Now);
scope.Commit();
}
}
AuditRecord GetSomeAuditInfo(Int userId, OpenWebClient client)
{
var result = client.ReadAuditRecord(userId);
return AuditRecord.FromWeb(result);
}
void WriteTheMessage(AMessage msg, OpenWebClient client)
{
using (var scope = new TransactionScope())
{
client.WriteTheMessage(msg.ToWeb());
scope.Commit();
}
}
void WriteAudit(AuditRecord audit, OpenWebClient client)
{
using (var scope = new TransactionScope())
{
client.WriteAudit(audit.ToWeb());
scope.Commit();
}
}
示例服务WCF
[ServiceContract]
interface IService
{
[OperationContract]
void WriteTheMessage(WebRecord message);
[OperationContract]
WebRecord ReadAuditRecord(int userId);
[OperationContract]
void WriteAudit(WebRecord audit);
}
class MyWebService : IService
{
[OperationBehavior(TransactionScopeRequired = true)]
void IService.WriteTheMessage(WebRecord record)
{
using (var connection = GetOpenConnection())
{
dowritethings;
}
}
[OperationBehavior(TransactionScopeRequired = false)]
WebRecord IService.ReadAuditRecord(WebRecord record)
{
using (var connection = GetOpenConnection())
{
return readthings;
}
}
[OperationBehavior(TransactionScopeRequired = true)]
void IService.WriteAudit(WebRecord record)
{
using (var connection = GetOpenConnection())
{
dowritethings;
}
}
}
答案 0 :(得分:2)
我在如何查看环境事务状态时进行了网络搜索,并提出了我放入监视窗口的Transaction.Current属性。 这显示在一次外部函数调用后我完全错过了Aborted。走进那里我发现我叫回归;从创建事务和提交事务之间的功能,因此中止。
感谢您的帮助
答案 1 :(得分:1)
您在服务器上打开的每个连接都是分布式实体。偶然,您经常在测试期间从连接池获得相同的物理连接。这是一种令人讨厌的行为,因为它会导致您在测试期间找不到问题。对于数据库,此设置以非确定性方式运行。
在任何情况下,您都应该在此处分发事务,因为WCF和SQL Server是不同的资源。这应该确定性地升级为使用MSDTC。
我假设事务已在此之前回滚
最有可能。使用WCF事务,您的代码始终设置了环境事务。可能在某个地方有一些你没注意到的异常。设置调试器以中断所有异常。使用Fiddler观察通过线路发送的响应。也许它们包含某种错误。 WCF跟踪是另一种选择。
如果这没有导致任何尝试创建可靠的repro。通常你会在过程中自己发现错误。