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

Add retry for BeginTransaction #183

Merged
merged 2 commits into from
Mar 1, 2022

Conversation

paulegradie
Copy link
Contributor

@paulegradie paulegradie commented Feb 17, 2022

Octopus Deploy dev teams have noticed transient connectivity issues when calling BeginTransaction in ReacTransaction.cs.
We are also behind 2 versions of SqlClient that may have beneficial bug fixes or performance improvements..

The objective of this PR is to:

  • Bump the version of SqlClient
  • Wrap these calls with retry logic provided by the RetryManager

Slack Thread

Benchmark Results

Before

TODO: get these running (currently hitting errors)

After

TODO: Same

@@ -89,7 +89,7 @@ public async Task OpenAsync(IsolationLevel isolationLevel)

// We use the synchronous overload here even though there is an async one, because the BeginTransactionAsync calls
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't seem like a async overload will be very helpful.

@@ -45,7 +45,7 @@
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="System.Diagnostics.Contracts" Version="4.3.0" />
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="2.1.4" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="4.1.0" />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend against using the sqlClient retry provider for now until we have a much more stable build environment. Currently, I'm only aware of this option for opening connections (not beginning transactions, but this advice applies to both in case that comes to light). Perhaps we don't want to make that change at all regardless.

@paulegradie paulegradie force-pushed the core/pg/add-retry-begin-transaction branch from 6cc0ac8 to 61aa573 Compare February 17, 2022 05:27
@@ -14,7 +14,7 @@ public IntegrationTestDatabase()
var username = Environment.GetEnvironmentVariable("NevermoreTestUsername");
var password = Environment.GetEnvironmentVariable("NevermoreTestPassword");
testDatabaseName = Environment.GetEnvironmentVariable("NevermoreTestDatabase") ?? "Nevermore-IntegrationTests";
var builder = new SqlConnectionStringBuilder($"Server={sqlInstance};Database={testDatabaseName};{(username == null ? "Trusted_connection=true;" : string.Empty)}")
var builder = new SqlConnectionStringBuilder($"Server={sqlInstance};Database={testDatabaseName};{(username == null ? "Trusted_connection=true;" : string.Empty)}; Encrypt=False;")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bumping the SqlClient altered the default for encryption. Most devs probably don't have this enabled on their dev SQL Server instance, so we can set this to avoid forcing folks to have to set another env var, or change their server settings.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will we need to add this on all connection strings that we have on Octopus?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah possibly / probably 👍 - good call

@paulegradie paulegradie force-pushed the core/pg/add-retry-begin-transaction branch from 61aa573 to 0c6b31e Compare February 17, 2022 05:41
@@ -13,7 +13,7 @@ public IntegrationTestDatabase()
var username = Environment.GetEnvironmentVariable("NevermoreTestUsername");
var password = Environment.GetEnvironmentVariable("NevermoreTestPassword");
testDatabaseName = Environment.GetEnvironmentVariable("NevermoreBenchmarkDatabase") ?? "Nevermore-Benchmarks";
var builder = new SqlConnectionStringBuilder($"Server={sqlInstance};Database={testDatabaseName};{(username == null ? "Trusted_connection=true;" : string.Empty)}")
var builder = new SqlConnectionStringBuilder($"Server={sqlInstance};Database={testDatabaseName};{(username == null ? "Trusted_connection=true;" : string.Empty)}; Encrypt=False;")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See below

@paulegradie paulegradie requested review from a team and droyad February 17, 2022 22:38
@paulegradie paulegradie marked this pull request as ready for review February 20, 2022 23:18
@paulegradie paulegradie force-pushed the core/pg/add-retry-begin-transaction branch from 0c6b31e to 14bb02d Compare February 21, 2022 03:13
Copy link
Contributor

@akirayamamoto akirayamamoto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments in there. Thanks Paul!

@@ -14,7 +14,7 @@ public IntegrationTestDatabase()
var username = Environment.GetEnvironmentVariable("NevermoreTestUsername");
var password = Environment.GetEnvironmentVariable("NevermoreTestPassword");
testDatabaseName = Environment.GetEnvironmentVariable("NevermoreTestDatabase") ?? "Nevermore-IntegrationTests";
var builder = new SqlConnectionStringBuilder($"Server={sqlInstance};Database={testDatabaseName};{(username == null ? "Trusted_connection=true;" : string.Empty)}")
var builder = new SqlConnectionStringBuilder($"Server={sqlInstance};Database={testDatabaseName};{(username == null ? "Trusted_connection=true;" : string.Empty)}; Encrypt=False;")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will we need to add this on all connection strings that we have on Octopus?


public static DbTransaction BeginTransactionWithRetry(this SqlConnection connection, IsolationLevel isolationLevel, string sqlServerTransactionName, RetryPolicy retryPolicy)
{
return (retryPolicy ?? RetryPolicy.NoRetry).LoggingRetries("Beginning Database Transaction").ExecuteAction(() => connection.BeginTransaction());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return (retryPolicy ?? RetryPolicy.NoRetry).LoggingRetries("Beginning Database Transaction").ExecuteAction(() => connection.BeginTransaction());
return (retryPolicy ?? RetryPolicy.NoRetry).LoggingRetries("Beginning Database Transaction").ExecuteAction(() => connection.BeginTransaction(isolationLevel, sqlServerTransactionName));

Don't we need to continue passing those arguments?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 Yes, haha of course. Thanks for catching this :D

@droyad
Copy link
Contributor

droyad commented Feb 21, 2022

Will we need to add this on all connection strings that we have on Octopus?

@akirayamamoto We might have to set it to False just like with this setting

@paulegradie paulegradie merged commit de7c60e into master Mar 1, 2022
@paulegradie paulegradie deleted the core/pg/add-retry-begin-transaction branch March 1, 2022 02:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants