@@ -84,8 +84,6 @@ public void DoCancel(MySqlCommand commandToCancel, MySqlCommand killCommand)
8484 // blocking the other thread for an extended duration.
8585 killCommand . CommandTimeout = 3 ;
8686 killCommand . ExecuteNonQuery ( ) ;
87-
88- commandToCancel . IsCanceled = true ;
8987 }
9088 }
9189
@@ -125,9 +123,30 @@ public void SetActiveReader(MySqlDataReader dataReader)
125123
126124 public void FinishQuerying ( )
127125 {
126+ bool clearConnection = false ;
128127 lock ( m_lock )
129128 {
130- VerifyState ( State . Querying , State . CancelingQuery ) ;
129+ if ( m_state == State . CancelingQuery )
130+ {
131+ m_state = State . ClearingPendingCancellation ;
132+ clearConnection = true ;
133+ }
134+ }
135+
136+ if ( clearConnection )
137+ {
138+ // KILL QUERY will kill a subsequent query if the command it was intended to cancel has already completed.
139+ // In order to handle this case, we issue a dummy query that will consume the pending cancellation.
140+ // See https://bugs.mysql.com/bug.php?id=45679
141+ var payload = new PayloadData ( new ArraySegment < byte > ( PayloadUtilities . CreateEofStringPayload ( CommandKind . Query , "DO SLEEP(0);" ) ) ) ;
142+ SendAsync ( payload , IOBehavior . Synchronous , CancellationToken . None ) . GetAwaiter ( ) . GetResult ( ) ;
143+ payload = ReceiveReplyAsync ( IOBehavior . Synchronous , CancellationToken . None ) . GetAwaiter ( ) . GetResult ( ) ;
144+ OkPayload . Create ( payload ) ;
145+ }
146+
147+ lock ( m_lock )
148+ {
149+ VerifyState ( State . Querying , State . ClearingPendingCancellation ) ;
131150 m_state = State . Connected ;
132151 m_activeReader = null ;
133152 m_activeCommand = null ;
@@ -313,7 +332,7 @@ private void VerifyConnected()
313332 {
314333 if ( m_state == State . Closed )
315334 throw new ObjectDisposedException ( nameof ( MySqlSession ) ) ;
316- if ( m_state != State . Connected && m_state != State . Querying && m_state != State . CancelingQuery && m_state != State . Closing )
335+ if ( m_state != State . Connected && m_state != State . Querying && m_state != State . CancelingQuery && m_state != State . ClearingPendingCancellation && m_state != State . Closing )
317336 throw new InvalidOperationException ( "MySqlSession is not connected." ) ;
318337 }
319338 }
@@ -669,6 +688,9 @@ private enum State
669688 // The session is connected to a server and the active query is being cancelled.
670689 CancelingQuery ,
671690
691+ // A cancellation is pending on the server and needs to be cleared.
692+ ClearingPendingCancellation ,
693+
672694 // The session is closing.
673695 Closing ,
674696
0 commit comments