MySqlConnector icon indicating copy to clipboard operation
MySqlConnector copied to clipboard

Unsupported: SAVEPOINT `__EFSavePoint`

Open tianxin8206 opened this issue 3 years ago • 1 comments

Software versions MySqlConnector version: 2.0.0 Server type (MySQL, MariaDB, Aurora, etc.) and version: MySQL 8.0.29 .NET version: 6.0 (Optional) ORM NuGet packages and versions: Pomelo.EntityFrameworkCore.MySql 6.0

Describe the bug I used the AddRangeAsync method to add data, and I got an error calling the SaveChangesAsync method.

Exception

MySqlConnector.MySqlException (0x80004005): Unsupported: SAVEPOINT `__EFSavePoint`
   at MySqlConnector.Core.ServerSession.ReceiveReplyAsyncAwaited(ValueTask`1 task) in /_/src/MySqlConnector/Core/ServerSession.cs:line 908
   at MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior) in /_/src/MySqlConnector/Core/ResultSet.cs:line 44
   at MySqlConnector.MySqlDataReader.ActivateResultSet(CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 126
   at MySqlConnector.MySqlDataReader.CreateAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, IDictionary`2 cachedProcedures, IMySqlCommand command, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, Cancellati
onToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 450
   at MySqlConnector.Core.CommandExecutor.ExecuteReaderAsync(IReadOnlyList`1 commands, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/C
ommandExecutor.cs:line 56
   at MySqlConnector.MySqlCommand.ExecuteNonQueryAsync(IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlCommand.cs:line 264
   at Microsoft.EntityFrameworkCore.Storage.RelationalTransaction.CreateSavepointAsync(String name, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalTransaction.CreateSavepointAsync(String name, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)

Code sample

public override async Task InsertManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
{
	var entityArray = entities.ToArray();
	var dbContext = await GetDbContextAsync();
	cancellationToken = GetCancellationToken(cancellationToken);

	foreach (var entity in entityArray)
	{
		CheckAndSetId(entity);
	}

	await dbContext.Set<TEntity>().AddRangeAsync(entityArray, cancellationToken);

	if (autoSave)
	{
		await dbContext.SaveChangesAsync(cancellationToken);
	}
}

Additional context Connection String: Data Source=192.168.50.218;Port=3306;User ID=root;Password=123456;Initial Catalog=jy_eadp_mkwszc;Charset=utf8mb4;SslMode=none;Min pool size=1

tianxin8206 avatar Sep 05 '22 07:09 tianxin8206

It looks like EF Core is trying to create a SQL statement to create the savepoint, instead of using MySqlTransaction.SaveAsync: https://github.com/dotnet/efcore/blob/release/6.0/src/EFCore.Relational/Storage/RelationalTransaction.cs#L289

I'm guessing it might be using SQL Server syntax instead of MySQL syntax. @lauxjpn any ideas?

bgrainger avatar Sep 05 '22 15:09 bgrainger

This isn't a problem with MySqlConnector itself AFAICT.

bgrainger avatar Jan 01 '23 22:01 bgrainger