-
Notifications
You must be signed in to change notification settings - Fork 335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement MySqlException.IsTransient #849
Comments
Similar to npgsql, this could probably just be driven from the
Because the default value of |
Which specific errors are classified as transient is of course a provider decision. However, the way I think about it is to err on the side of false positives, rather than conservatively erring on the side of false negatives. A false positive would typically mean a needless retry (which doesn't seem critical), whereas a false negative would mean throwing where a retry may have result in success. |
@roji What are your thoughts on |
That's an important question, I addressed it in the proposal:
In other words, IsTransient=true doesn't in any way imply that the command alone should be retried for a possibly successful outcome - only that the error itself is (possibly) transient. It's indeed the responsibility of the layer above the ADO.NET provider to track commands within the transaction, and I'd expect that layer to rollback and retry the entire transaction when getting a transient error. This is exactly how EF Core behaves (also employing transaction savepoints). Let me know if that makes sense to you. |
Thanks, that's really helpful. (And sorry I missed that you had already explicitly addressed this.) |
Sure thing, and starting out from the Pomelo list sounds like a good idea. It's interesting that a MySqlErrorCode is used - does that mean there are two error codes in MySql, i.e. the 5-character SqlState and also this? I wonder what the pros/cons of each are. |
A user points out that this code path logs an error then throws an exception that will be MySqlConnector/src/MySqlConnector/Core/ServerSession.cs Lines 376 to 377 in 4cd45f6
Logging an error (that may be passed through to the client's logs) may be too serious in cases when we expect that user code will retry to handle this error. I guess philosophically it's going to come down to who sets the definition of "Error": MySqlConnector, or the consuming application, and what counts as an error? |
It's definitely an interesting discussion, but it seems somewhat orthogonal to error transience. Even for a totally non-transient error, the application may catch the exception above in the stack and handle it (e.g. by connecting to another database), so it could be claimed that the low-level driver shouldn't be logging. However, that would basically mean that no driver error can ever be logged, since who knows whether the calling application consider it an error or not... Pragmatically speaking, if a low-level component (like a DB driver) logs (and that generally seems like a good idea), I think it should do so regardless of what's going up the stack, and cannot assume that transient errors would actually be retried; it can't know if a retry strategy is configured. Users always have the option to selectively disable logging of certain messages based on rules configured in their logging library... It's also possible for the driver to be configurable as to whether it logs for transient errors, though I'd personally wait and see if lots of people actually request that. |
I used Pomelo's list as the definition for |
Great to see this getting implemented... At some point when it's released, the Pomelo provider could simply call IsTransient on your exception. |
Yes; I opened PomeloFoundation/Pomelo.EntityFrameworkCore.MySql#1285 to track that. |
Added in 1.3.0. |
dotnet/runtime#34817 introduces DbException.IsTransient for .NET 5.0, database-agnostic transient error detection. Not sure which transient errors Sqlite surfaces (e.g. locking/transactions?), these could be surfaced via this property.
MySQL and PostgreSQL both expose SQLSTATE codes directly from the database. If the actual codes and their transience overlap to a considerable amount, we should consider bringing some logic into DbException itself, i.e. provide a default implementation of IsTransient which identifies some hard-coded values in SqlState and returns true.
Here's the current Npgsql implementation for IsTransient.
The text was updated successfully, but these errors were encountered: