diff --git a/src/MySqlConnector/Core/EnlistedTransactionBase.cs b/src/MySqlConnector/Core/EnlistedTransactionBase.cs index 73a156846..e8506ee14 100644 --- a/src/MySqlConnector/Core/EnlistedTransactionBase.cs +++ b/src/MySqlConnector/Core/EnlistedTransactionBase.cs @@ -10,6 +10,9 @@ internal abstract class EnlistedTransactionBase : IEnlistmentNotification // Whether the connection is idle, i.e., a client has closed it and is no longer using it public bool IsIdle { get; set; } + // Whether to enter the PREPARED state, The rollback operation needs to determine if the Xa transaction has entered the PREPARED state. + public bool IsPrepared { get; set; } + public Transaction Transaction { get; private set; } public void Start() @@ -20,8 +23,16 @@ public void Start() void IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment) { - OnPrepare(preparingEnlistment); - preparingEnlistment.Prepared(); + try + { + OnPrepare(preparingEnlistment); + IsPrepared = true; + preparingEnlistment.Prepared(); + } + catch (Exception ex) + { + preparingEnlistment.ForceRollback(ex); + } } void IEnlistmentNotification.Commit(Enlistment enlistment) diff --git a/src/MySqlConnector/Core/XaEnlistedTransaction.cs b/src/MySqlConnector/Core/XaEnlistedTransaction.cs index 3937d420d..69ef49255 100644 --- a/src/MySqlConnector/Core/XaEnlistedTransaction.cs +++ b/src/MySqlConnector/Core/XaEnlistedTransaction.cs @@ -37,7 +37,9 @@ protected override void OnRollback(Enlistment enlistment) { try { - ExecuteXaCommand("END"); + if (!IsPrepared) + ExecuteXaCommand("END"); + ExecuteXaCommand("ROLLBACK"); } catch (MySqlException ex) when (ex.ErrorCode is MySqlErrorCode.XARBDeadlock)