-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Expose transaction savepoints in ADO.NET #33397
Comments
Added API proposal with notes /cc @David-Engel @cheenamalhotra @bgrainger @bricelam @ajcvickers @stephentoub @terrajobst @mgravell |
There can be user-visible side-effects (e.g., raising an error if that savepoint name doesn't exist, making it an error in the future to roll back to that savepoint name after it's released). My inclination is to make it throw |
Since DB terminology universally uses "savepoint" (not "save point"; see docs linked from OP), the parameter names should be |
Sorry for the delayed response @bgrainger, these are busy times.
Right - release can be visible for code depending on an error being thrown when the API is used incorrectly etc. I don't have very strong feelings here, but I don't think these negative cases typically inform API decisions in a significant way.
To be concrete, all databases I know of which support savepoints support Release, except SQL Server where this would be a no-op; so we're mainly discussing whether SqlClient would inherit the no-op behavior or if it would have to override for that behavior. This would have very little actual consequences either way.
Well, anyone using the new savepoint API on older providers is very likely to call Save/Rollback before Release, at which point they'd get the NotSupportedException anyway.
Sounds good. The naming was taken from SqlClient's current naming, but the new DbTransaction methods can have different parameter names (though this may get slightly confusing for people using named parameters). FWIW Npgsql already uses a different parameter name here ( |
Agreed, and I'm happy with the current proposal.
Thanks. One final thing: shouldn't this be
|
Absolutely, thanks for catching it (amended). I think this is ready for review - though am wondering if return a Task rather than ValueTask is still the right thing here (/cc @stephentoub). Am marking this as ready for review. |
PR submitted: #34561. This is pretty much a simple copy-paste of the proposal above, but @ajcvickers @bgrainger always good to have another pair eyes to make sure things are good.
After discussion with @stephentoub, leaving these methods to return a Task as the allocation isn't likely to matter for methods which are almost certain to do a database network roundtrip, and which don't return a value. @stephentoub @terrajobst I'm really hoping we can get this in for preview4 as EF Core needs to build some functionality over it. |
@FransBouma just realized I had forgotten to cc you on this, in case you're interested. |
@roji Looks good to me :) Yeah 'Release' isn't really that interesting, as in general you want to go back to a given point in time in the transaction. It's a niche feature tho. I support it through my ORM API, and use reflection to obtain the Save method on the ADO.NET provider so having a generic interface for this is great, saves me the trouble for reflecting over it :) |
Great, that's the perfect example for why this is needed in System.Data :) |
@ajcvickers @roji let me know if you still want to do this for .NET 5 and I'll schedule a review. |
@terrajobst yes, if possible I'd still like to get this in for 5... |
namespace System.Data.Common
{
public class DbTransaction
{
public virtual Task SaveAsync(string savepointName, CancellationToken cancellationToken = default);
public virtual Task RollbackAsync(string savepointName, CancellationToken cancellationToken = default);
public virtual Task ReleaseAsync(string savepointName, CancellationToken cancellationToken = default);
public virtual void Save(string savepointName);
public virtual void Rollback(string savepointName);
public virtual void Release(string savepointName);
public virtual bool SupportsSavepoints { get; }
}
} |
PR: #34561 |
Aligning with the System.Data savepoints API: dotnet/runtime#33397 (comment) Part of #20409 (May 20)
Aligning with the System.Data savepoints API: dotnet/runtime#33397 (comment) Part of #20409 (May 20)
The SQL Standard defines the concept of savepoints, which allow one to partially roll back a transaction; multiple savepoints may be defined, but only within a transaction. These seem to be well-supported in a uniform way across databases - although the SQL syntax is a bit quirky across databases. SqlClient and Npgsql already expose methods for savepoints on their DbTransaction implementations, but there's probably value in exposing these on DbTransaction.
API Proposal
Notes
AreSavepointsSupported
should throw InvalidOperationException if accessed with closed connection. We could introduce a non-virtual user-facing property to check for this, calling a protected virtual property implemented by the provider, but we can't know if a transaction has completed (or has been disposed). So it's probably better to leave this to the provider, documenting the correct behavior (even when the specific provider always supports savepoints).Edit history
The text was updated successfully, but these errors were encountered: