大家好,感谢您的提前帮助。我正在开发.Net Core 3.1 Web应用程序,该应用程序是Twilio api服务的终结点,该服务从Twilio api接收更新帖子。然后,使用EF Core将这些帖子记录到SQL Server 2012数据库中。但是,我间歇性地遇到错误:
System.InvalidOperationException:此SqlTransaction已完成;它不再可用。在Microsoft.Data.SqlClient.SqlTransaction.ZombieCheck()在Microsoft.Data.SqlClient.SqlTransaction.Commit()在Microsoft.EntityFrameworkCore.Storage.RelationalTransaction.Commit()在Twilio_Secure_Endpoint.BusinessLogic.LogSMSTransaction。<> c__DisplayClass0_0。<。ctor > b__0()在E:\ Hugh \ Documents \ Visual Studio 2019 \ Projects \ Twilio_Secure_Endpoint \ Twilio_Secure_Endpoint \ BusinessLogic \ LogSMSTransaction.cs:line 57 at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions。<> c.b__0_0(Microsoft.EntityFrameworkCore上的(Action operationScoped) .Microsoft的.Storage.ExecutionStrategy.ExecuteImplementation [TState,TResult](Func
3 operation, Func
3 verifySucceeded,TState状态)位于Twilio_Secure_Endpoints.BusinessLogic.LogSMSt。 smsMessage)),位于E:\ Hugh \ Documents \ Visual Studio 2019 \ Projects \ Twilio_Secure_Endpoint \ Twilio_Secure_Endpoint \ BusinessLogic \ LogSMSTransaction.cs:第59行Twilio_Secure_Endpoint.Controllers.SmsController.Index(tbl_Log_SMSMessages smsMessage)
我首先尝试启用连接弹性:
public class myContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(connString, sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.EnableRetryOnFailure(
maxRetryCount: 15,
maxRetryDelay: TimeSpan.FromSeconds(30),
errorNumbersToAdd: null);
sqlOptions.CommandTimeout((int)TimeSpan.FromMinutes(10).TotalSeconds);
});
}
public DbSet<tbl_Log_SMSMessages> tbl_Log_SMSMessages { get; set; }
public DbSet<tbl_Log_SMSUnsubscribe> tbl_Log_SMSUnsubscribe { get; set; }
public DbSet<tbl_Log_SMSPollingMessages> tbl_Log_SMSPollingMessages { get; set; }
public DbSet<tbl_Log_SMSValidation> tbl_Log_SMSValidation { get; set; }
}
从控制器调用的插入例程如下:
public async Task LogSMSResponse(tbl_Log_SMSMessages smsMessage)
{
try
{
//
// Log to database
using (var ctx = new myContext())
{
ctx.tbl_Log_SMSMessages.Add(new tbl_Log_SMSMessages()
{
AccountSid = smsMessage.AccountSid,
ApiVersion = smsMessage.ApiVersion,
Body = smsMessage.Body,
Direction = "Incoming",
From = smsMessage.From,
FromCity = smsMessage.FromCity,
FromCountry = smsMessage.FromCountry,
FromState = smsMessage.FromState,
FromZip = smsMessage.FromZip,
MessageSid = smsMessage.MessageSid,
NumMedia = smsMessage.NumMedia,
NumSegments = smsMessage.NumSegments,
SmsMessageSid = smsMessage.SmsMessageSid,
SmsStatus = smsMessage.SmsStatus,
ToCity = smsMessage.ToCity,
ToCountry = smsMessage.ToCountry,
To = smsMessage.To,
ToState = smsMessage.ToState,
ToZip = smsMessage.ToZip,
TimeEntered = DateTime.Now
}); ;
await ctx.SaveChangesAsync();
}
}
catch (Exception ex)
{
SendEmail sendEmail = new SendEmail("Log_SMS_Async.LogResponse Error", ex.ToString());
}
}``
然后我尝试使用transaction.commit:
public LogSMSTransaction(tbl_Log_SMSMessages smsMessage)
{
//
// https://forums.asp.net/t/2168609.aspx?Microsoft+Data+SqlClient+SqlTransaction+ZombieCheck+with+EF+Core
// https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency#option-4---manually-track-the-transaction
//
using (var db = new myContext())
{
var strategy = db.Database.CreateExecutionStrategy();
strategy.Execute(() =>
{
using (var context = new myContext())
{
using (var transaction = context.Database.BeginTransaction())
{
context.tbl_Log_SMSMessages.Add(new tbl_Log_SMSMessages()
{
AccountSid = smsMessage.AccountSid,
ApiVersion = smsMessage.ApiVersion,
Body = smsMessage.Body,
Direction = "Incoming",
From = smsMessage.From,
FromCity = smsMessage.FromCity,
FromCountry = smsMessage.FromCountry,
FromState = smsMessage.FromState,
FromZip = smsMessage.FromZip,
MessageSid = smsMessage.MessageSid,
NumMedia = smsMessage.NumMedia,
NumSegments = smsMessage.NumSegments,
SmsMessageSid = smsMessage.SmsMessageSid,
SmsStatus = smsMessage.SmsStatus,
ToCity = smsMessage.ToCity,
ToCountry = smsMessage.ToCountry,
To = smsMessage.To,
ToState = smsMessage.ToState,
ToZip = smsMessage.ToZip,
TimeEntered = DateTime.Now
}); ;
context.SaveChanges();
transaction.Commit();
}
}
});
}
}
仍然出现错误。我意识到该错误消息表示某种类型的连接丢失,但不知道从这里去哪里。