Skip to content
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

Delayed durability support #317

Open
rgroenewoudt opened this issue Nov 19, 2019 · 5 comments
Open

Delayed durability support #317

rgroenewoudt opened this issue Nov 19, 2019 · 5 comments
Labels
💡 Enhancement Issues that are feature requests for the drivers we maintain. 🙌 Up-for-Grabs Issues that are ready to be picked up for anyone interested. Please self-assign and remove the label ✨ Good first issue Issues that are simple enough for newcomers

Comments

@rgroenewoudt
Copy link

Is your feature request related to a problem? Please describe.

SQL Server 2014 supports delayed durability. This requires a slight different SQL for the commit:
COMMIT WITH (DELAYED_DURABILITY = ON)

Describe the solution you'd like

A property in SqlTransaction, for example bool DelayedDurability

Describe alternatives you've considered

Manually executing the SQL BEGIN TRANSACTION and COMMIT is the alternative but it would be nice if it's builtin.

@cheenamalhotra cheenamalhotra added the 💡 Enhancement Issues that are feature requests for the drivers we maintain. label Nov 19, 2019
@cheenamalhotra
Copy link
Member

Thanks for filing an issue for this request.
We'll investigate and see if we can support it sometime in future.

@cheenamalhotra cheenamalhotra added 🙌 Up-for-Grabs Issues that are ready to be picked up for anyone interested. Please self-assign and remove the label ✨ Good first issue Issues that are simple enough for newcomers labels Oct 21, 2020
@Grauenwolf
Copy link

Here are the two pieces that appear to be relevant.

//Pre-20005

        // For Transactions
        public const string TRANS_BEGIN = "BEGIN TRANSACTION";
        public const string TRANS_COMMIT = "COMMIT TRANSACTION";
        public const string TRANS_ROLLBACK = "ROLLBACK TRANSACTION";
        public const string TRANS_IF_ROLLBACK = "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION";
        public const string TRANS_SAVE = "SAVE TRANSACTION";


//2005 and later

        internal enum TransactionManagerRequestType
        {
            GetDTCAddress = 0,
            Propagate = 1,
            Begin = 5,
            Promote = 6,
            Commit = 7,
            Rollback = 8,
            Save = 9
        };

Looking at the TDS spec I don't see anything about DELAYED_DURABILITY in the transaction manager section.

This means that it will need custom handling for DELAYED_DURABILITY. Instead of calling _parser.TdsExecuteTransactionManagerRequest, it will need to call _parser.TdsExecuteSQLBatch.

Threading this through is going to be quite difficult, which probably explains why no one has taken up the ticket.

@rgroenewoudt
Copy link
Author

Shouldn't this be added to the TDS spec and forwarded to the SQL Server team?

@roji
Copy link
Member

roji commented Feb 15, 2023

@Grauenwolf aren't normal and distributed ("transaction manager") transactions being confused above? Delayed durability transactions don't seem to be very relevant for distributed transactions (where they always seem to be fully durable, see table).

In other words, isn't this simply about adding an option to the SqlTransction.Commit API which would cause SqlClient to send COMMIT WITH (DELAYED_DURABILITY = ON)?

@vonzshik
Copy link

@roji I'm afraid he's correct. Every transaction request (commit, rollback, etc) goes through SqlServer's transaction manager.

internal void Commit()
{
using (TryEventScope.Create("SqlInternalTransaction.Commit | API | Object Id {0}", ObjectID))
{
if (_innerConnection.IsLockedForBulkCopy)
{
throw SQL.ConnectionLockedForBcpEvent();
}
_innerConnection.ValidateConnectionForExecute(null);
// If this transaction has been completed, throw exception since it is unusable.
try
{
// COMMIT ignores transaction names, and so there is no reason to pass it anything. COMMIT
// simply commits the transaction from the most recent BEGIN, nested or otherwise.
_innerConnection.ExecuteTransaction(SqlInternalConnection.TransactionRequest.Commit, null, IsolationLevel.Unspecified, null, false);

internal override void ExecuteTransaction(TransactionRequest transactionRequest, string name, System.Data.IsolationLevel iso, SqlInternalTransaction internalTransaction, bool isDelegateControlRequest)
{
if (IsConnectionDoomed)
{ // doomed means we can't do anything else...
if (transactionRequest == TransactionRequest.Rollback
|| transactionRequest == TransactionRequest.IfRollback)
{
return;
}
throw SQL.ConnectionDoomed();
}
if (transactionRequest == TransactionRequest.Commit
|| transactionRequest == TransactionRequest.Rollback
|| transactionRequest == TransactionRequest.IfRollback)
{
if (!Parser.MARSOn && Parser._physicalStateObj.BcpLock)
{
throw SQL.ConnectionLockedForBcpEvent();
}
}
string transactionName = (null == name) ? string.Empty : name;
ExecuteTransaction2005(transactionRequest, transactionName, iso, internalTransaction, isDelegateControlRequest);
}

_parser.TdsExecuteTransactionManagerRequest(null, requestType, transactionName, isoLevel,
ConnectionOptions.ConnectTimeout, internalTransaction, stateObj, isDelegateControlRequest);

https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/0fb28ba5-ddcb-4d02-95c3-aa5b05ec6092

And currently transaction manager request lacks a field to pass DELAYED_DURABILITY.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💡 Enhancement Issues that are feature requests for the drivers we maintain. 🙌 Up-for-Grabs Issues that are ready to be picked up for anyone interested. Please self-assign and remove the label ✨ Good first issue Issues that are simple enough for newcomers
Projects
None yet
Development

No branches or pull requests

5 participants