The connector shows some deadlock behavior that does not occur when using the database directly or when using Connector/NET.
With UseXaTransactions=False, and the following simple table:
CREATE TABLE `orders`(
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`description` VARCHAR(50),
PRIMARY KEY (`id`)
) ENGINE=INNODB;
Let's run a program that does the following, from two threads simultaneously:
- Open a transaction scope.
- SELECT MAX(id) FROM orders FOR UPDATE.
- INSERT INTO orders.
- Complete the transaction scope.
What should happen (and does with Connector/NET or directly on the database):
One thread should get the lock, while the other gets temporarily stuck on step 2. The winning thread finishes the rest of its work. The losing thread then gets the lock and can finish its work.
What currently happens differently with MySqlConnector:
As soon as the winning thread begins its INSERT, without even committing, the losing thread gets a deadlock exception:
MySqlException: Deadlock found when trying to get lock; try restarting transaction
Here is a simple program we can use to reproduce this on the table mentioned above:
internal class Program
{
public static void Main(string[] args)
{
Task.Run(() => Perform(1));
Perform(2);
Console.ReadKey();
}
private static void Perform(int i)
{
// This TransactionScope may be overly configured, but let's stick with the one I am actually using
using (var transactionScope = new System.Transactions.TransactionScope(
TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted, Timeout = TimeSpan.FromMinutes(10) }, TransactionScopeAsyncFlowOption.Enabled))
{
using (var connection = new MySqlConnection("Server=localhost;Uid=user;Pwd=pwd;TreatTinyAsBoolean=False;UseAffectedRows=True;SslMode=None;UseXaTransactions=False;"))
using (var command = connection.CreateCommand())
{
command.CommandText = @"SELECT MAX(id) FROM orders FOR UPDATE;";
connection.Open();
Console.WriteLine(i + " locking");
command.ExecuteScalar();
}
using (var connection = new MySqlConnection("Server=localhost;Uid=user;Pwd=pwd;TreatTinyAsBoolean=False;UseAffectedRows=True;SslMode=None;UseXaTransactions=False;"))
using (var command = connection.CreateCommand())
{
command.CommandText = @"INSERT INTO orders (description) VALUES ('blabla'), ('blablabla');";
connection.Open();
Console.WriteLine(i + " inserting");
command.ExecuteNonQuery();
}
transactionScope.Complete();
}
}
}
The connector shows some deadlock behavior that does not occur when using the database directly or when using Connector/NET.
With
UseXaTransactions=False, and the following simple table:Let's run a program that does the following, from two threads simultaneously:
What should happen (and does with Connector/NET or directly on the database):
One thread should get the lock, while the other gets temporarily stuck on step 2. The winning thread finishes the rest of its work. The losing thread then gets the lock and can finish its work.
What currently happens differently with MySqlConnector:
As soon as the winning thread begins its INSERT, without even committing, the losing thread gets a deadlock exception:
Here is a simple program we can use to reproduce this on the table mentioned above: