Skip to content

Commit

Permalink
Add savepoint API to DbTransaction (#34561)
Browse files Browse the repository at this point in the history
Closes #33397
  • Loading branch information
roji authored Aug 5, 2020
1 parent 890fe97 commit 8250b0a
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/libraries/System.Data.Common/ref/System.Data.Common.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2441,6 +2441,13 @@ protected virtual void Dispose(bool disposing) { }
public virtual System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
public abstract void Rollback();
public virtual System.Threading.Tasks.Task RollbackAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual bool SupportsSavepoints { get { throw null; } }
public virtual System.Threading.Tasks.Task SaveAsync(string savepointName, System.Threading.CancellationToken cancellationToken = default) { throw null; }
public virtual System.Threading.Tasks.Task RollbackAsync(string savepointName, System.Threading.CancellationToken cancellationToken = default) { throw null; }
public virtual System.Threading.Tasks.Task ReleaseAsync(string savepointName, System.Threading.CancellationToken cancellationToken = default) { throw null; }
public virtual void Save(string savepointName) { throw null; }
public virtual void Rollback(string savepointName) { throw null; }
public virtual void Release(string savepointName) { throw null; }
}
public enum GroupByBehavior
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,121 @@ public virtual Task RollbackAsync(CancellationToken cancellationToken = default)
return Task.FromException(e);
}
}

#region Savepoints

/// <summary>
/// Gets a value that indicates whether this <see cref="DbTransaction" /> instance supports database savepoints.
/// If <see langword="false" />, the methods <see cref="SaveAsync" />,
/// <see cref="RollbackAsync(string, System.Threading.CancellationToken)"/> and <see cref="ReleaseAsync" /> as
/// well as their synchronous counterparts are expected to throw <see cref="NotSupportedException" />.
/// </summary>
/// <returns>
/// <see langword="true" /> if this <see cref="DbTransaction"/> instance supports database savepoints; otherwise,
/// <see langword="false" />.
/// </returns>
public virtual bool SupportsSavepoints => false;

/// <summary>
/// Creates a savepoint in the transaction. This allows all commands that are executed after the savepoint was
/// established to be rolled back, restoring the transaction state to what it was at the time of the savepoint.
/// </summary>
/// <param name="savepointName">The name of the savepoint to be created.</param>
/// <param name="cancellationToken">
/// An optional token to cancel the asynchronous operation. The default value is <see cref="CancellationToken.None" />.
/// </param>
/// <returns>A <see cref="Task " /> representing the asynchronous operation.</returns>
public virtual Task SaveAsync(string savepointName, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
return Task.FromCanceled(cancellationToken);
}

try
{
Save(savepointName);
return Task.CompletedTask;
}
catch (Exception e)
{
return Task.FromException(e);
}
}

/// <summary>
/// Rolls back all commands that were executed after the specified savepoint was established.
/// </summary>
/// <param name="savepointName">The name of the savepoint to roll back to.</param>
/// <param name="cancellationToken">
/// An optional token to cancel the asynchronous operation. The default value is <see cref="CancellationToken.None" />.
/// </param>
/// <returns>A <see cref="Task " /> representing the asynchronous operation.</returns>
public virtual Task RollbackAsync(string savepointName, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
return Task.FromCanceled(cancellationToken);
}

try
{
Rollback(savepointName);
return Task.CompletedTask;
}
catch (Exception e)
{
return Task.FromException(e);
}
}

/// <summary>
/// Destroys a savepoint previously defined in the current transaction. This allows the system to
/// reclaim some resources before the transaction ends.
/// </summary>
/// <param name="savepointName">The name of the savepoint to release.</param>
/// <param name="cancellationToken">
/// An optional token to cancel the asynchronous operation. The default value is <see cref="CancellationToken.None" />.
/// </param>
/// <returns>A <see cref="Task " /> representing the asynchronous operation.</returns>
public virtual Task ReleaseAsync(string savepointName, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
return Task.FromCanceled(cancellationToken);
}

try
{
Release(savepointName);
return Task.CompletedTask;
}
catch (Exception e)
{
return Task.FromException(e);
}
}

/// <summary>
/// Creates a savepoint in the transaction. This allows all commands that are executed after the savepoint was
/// established to be rolled back, restoring the transaction state to what it was at the time of the savepoint.
/// </summary>
/// <param name="savepointName">The name of the savepoint to be created.</param>
public virtual void Save(string savepointName) => throw new NotSupportedException();

/// <summary>
/// Rolls back all commands that were executed after the specified savepoint was established.
/// </summary>
/// <param name="savepointName">The name of the savepoint to roll back to.</param>
public virtual void Rollback(string savepointName) => throw new NotSupportedException();

/// <summary>
/// Destroys a savepoint previously defined in the current transaction. This allows the system to
/// reclaim some resources before the transaction ends.
/// </summary>
/// <param name="savepointName">The name of the savepoint to release.</param>
public virtual void Release(string savepointName) {}

#endregion
}
}

0 comments on commit 8250b0a

Please sign in to comment.