This is my first WCF both client and server side. SQL server 2008.
I'm forced to use TransactionScope transactions from within my windows forms application that's running as a client against a WCF service. I've not used this type of transaction before, usually using connection.BeginTransaction() which I like because it's easier to follow what's going on.
I call a function (that I'm hoping is nesting transactions) but one of my calls to create a new TransactionScope instance falls over with "The transaction has aborted" exception. Inner exception is null. I'm assuming that the transaction has rolled back prior to this, but I've no idea how to track if there was an ambient transaction in progress and what the status of that was.
example client (not real code. I've checked all funcs are using scope.Commit()) Any help on how to track down the problem please?
(often I receive error messages about having to start the MSDTC service, which I do, but I don't understand why it's using distributed when there's a single database/wcf service)
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();
}
}
example service 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;
}
}
}