Ich habe ein ASP.Net WebAPI-Instanz-Setup, das eine MySQL-Datenbank für den Speicher verwendet. Ich habe eine ActionFilter
geschrieben, die das Erstellen eines TransactionScope
für die Lebensdauer einer einzelnen Endpunktanforderung behandelt.TransactionScope mit MySQL und verteilten Transaktionen
public async Task<HttpResponseMessage> ExecuteActionFilterAsync(
HttpActionContext actionContext,
CancellationToken cancellationToken,
Func<Task<HttpResponseMessage>> continuation)
{
var transactionScopeOptions = new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted };
using (var transaction = new TransactionScope(TransactionScopeOption.RequiresNew, transactionScopeOptions, TransactionScopeAsyncFlowOption.Enabled))
{
var handledTask = await continuation();
transaction.Complete();
return handledTask;
}
}
Dann in den Endpunkten habe ich verschiedene Abfragen/Befehle, die zum Öffnen/Schließen Verbindungen der autoenlist=true
Funktionalität von DbConnection
‚s mit. Ein Beispiel Endpunkt sein kann:
public async Task<IHttpActionResult> CreateStuffAsync()
{
var query = this.queryService.RetrieveAsync();
// logic to do stuff
var update = this.updateService.Update(query);
return this.Ok();
}
Ich mache keinen einzigen DbConnection
und geben es um von oben, da dies ein einfaches Beispiel ist, wenn in der Praxis übergibt die Verbindung zwischen den Diensten eine große Refactoring erfordern würde (obwohl wenn nötig, kann dies getan werden). Ich lese auch, dass es besser ist, die Verbindungen nach Bedarf zu öffnen/zu schließen (d. H. Sie für so wenig Zeit wie möglich offen zu halten). Das queryService
und updateService
open/close DbConnection
‚s über using
Aussagen:
var factory = DbProviderFactories.GetFactory("MySql.Data.MySqlClient");
using (var connection = factory.CreateConnection())
{
connection.ConnectionString = "Data Source=localhost;Initial Catalog=MyDatabase;User ID=user;Password=password;Connect Timeout=300;AutoEnlist=true;";
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
var result = await connection.QueryAsync(Sql).ConfigureAwait(false);
return result;
}
Die gleichen DbConnection
ist in der Regel nicht für mehrere Abfragen innerhalb der gleichen API-Endpunkt-Anforderung verwendet - aber die gleiche Verbindungszeichenfolge ist.
Intermittently Ich sehe eine ausgelöste Ausnahme beim Versuch, die Verbindung zu öffnen:
"ExceptionType": "System.NotSupportedException",
"ExceptionMessage": "System.NotSupportedException: MySQL Connector/Net does not currently support distributed transactions.\r\n at MySql.Data.MySqlClient.ExceptionInterceptor.Throw(Exception exception)\r\n at MySql.Data.MySqlClient.MySqlConnection.EnlistTransaction(Transaction transaction)\r\n at MySql.Data.MySqlClient.MySqlConnection.Open()"
Ich verstehe nicht, warum es versucht, die Transaktion zu einer verteilten Transaktion zu eskalieren, wenn alle Verbindungen sind gegen die gleiche Datenbank. Oder missverstanden/missbrauche ich die TransactionScope
und DbConnection
Instanzen?
Bradly Grainger hat Recht. Es läuft gut. Ich benutze eine andere MySQL Verbindung anstelle von MySqlConnection.Ich vermute, dass MySqlConnection von Oracle nicht mehr entwickelt wird. Ich habe bestätigt, dass https://www.devart.com/dotconnect/mysql/ Ihr Problem lösen kann. Versuch es bitte. –