Skip to content

Commit d37e310

Browse files
committed
🐞fix: LockAsync does not honour transactions
ApplicationLock.LockAsync did not pass open transaction to the underlying connections, causing exceptions.
1 parent 0953d5b commit d37e310

File tree

4 files changed

+17
-14
lines changed

4 files changed

+17
-14
lines changed

src/Simpleverse.Repository.Db/Simpleverse.Repository.Db.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
1414
<PackageTags>Dapper, Bulk, Merge, Upsert, Delete, Insert, Update, Repository</PackageTags>
1515
<PackageLicenseFile>LICENSE</PackageLicenseFile>
16-
<Version>2.1.23</Version>
16+
<Version>2.1.24</Version>
1717
<Description>High performance operation for MS SQL Server built for Dapper ORM. Including bulk operations Insert, Update, Delete, Get as well as Upsert both single and bulk.</Description>
18-
<AssemblyVersion>2.1.23.0</AssemblyVersion>
19-
<FileVersion>2.1.23.0</FileVersion>
18+
<AssemblyVersion>2.1.24.0</AssemblyVersion>
19+
<FileVersion>2.1.24.0</FileVersion>
2020
<RepositoryUrl>https://github.com/lukaferlez/Simpleverse.Repository</RepositoryUrl>
2121
<PackageReadmeFile>README.md</PackageReadmeFile>
2222
<EmbedAllSources>true</EmbedAllSources>

src/Simpleverse.Repository.Db/SqlServer/ApplicationLock.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using Microsoft.Data.SqlClient;
22
using System;
33
using System.Data;
4-
using System.Data.Common;
54
using System.IO.Hashing;
65
using System.Text;
76
using System.Threading.Tasks;
@@ -29,7 +28,7 @@ public class ApplicationLockScope : IDisposable
2928

3029
private bool wasClosed;
3130
private readonly SqlConnection connection;
32-
private DbTransaction transaction;
31+
private IDbTransaction transaction;
3332

3433
public ApplicationLockScope(SqlConnection connection)
3534
{
@@ -50,7 +49,7 @@ public async Task<bool> LockAsync(params object[] keyItems)
5049
transaction = await connection.BeginTransactionAsync(IsolationLevel.ReadCommitted);
5150
}
5251

53-
return await connection.GetAppLockAsync(key);
52+
return await connection.GetAppLockAsync(key, transaction: transaction);
5453
}
5554

5655
protected virtual void Dispose(bool disposing)

src/Simpleverse.Repository.Db/SqlServer/SqlConnectionExtensions.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ UNION ALL
3737
return insertedTableName;
3838
}
3939

40-
public static async Task<R> ExecuteAsyncWithTransaction<R>(this SqlConnection conn, Func<SqlConnection, SqlTransaction, Task<R>> function)
40+
public static async Task<R> ExecuteAsyncWithTransaction<R>(
41+
this SqlConnection conn,
42+
Func<SqlConnection, IDbTransaction, Task<R>> function
43+
)
4144
{
4245
using (var tran = conn.BeginTransaction())
4346
{
@@ -49,7 +52,7 @@ public static async Task<R> ExecuteAsyncWithTransaction<R>(this SqlConnection co
4952

5053
#region AppLock
5154

52-
public static async Task<bool> GetAppLockAsync(this SqlConnection connection, string key, SqlTransaction transaction = null)
55+
public static async Task<bool> GetAppLockAsync(this SqlConnection connection, string key, IDbTransaction transaction = null)
5356
{
5457
if (key.Length > 255)
5558
throw new ArgumentOutOfRangeException(nameof(key), "ength of the key used for locking must be less then 256 characters.");
@@ -67,7 +70,7 @@ select @result
6770
return result == 0 || result == 1;
6871
}
6972

70-
public static async Task<bool> ReleaseAppLockAsync(this SqlConnection connection, string key, SqlTransaction transaction = null)
73+
public static async Task<bool> ReleaseAppLockAsync(this SqlConnection connection, string key, IDbTransaction transaction = null)
7174
{
7275
if (key.Length > 255)
7376
throw new ArgumentOutOfRangeException(nameof(key), "Length of the key used for locking must be less then 256 characters.");
@@ -88,7 +91,7 @@ select @result
8891
public static Task<R> ExecuteWithAppLockAsync<R>(
8992
this SqlConnection conn,
9093
string resourceIdentifier,
91-
Func<SqlConnection, SqlTransaction, Task<R>> function
94+
Func<SqlConnection, IDbTransaction, Task<R>> function
9295
)
9396
{
9497
return conn.ExecuteAsyncWithTransaction(
@@ -97,9 +100,9 @@ Func<SqlConnection, SqlTransaction, Task<R>> function
97100
}
98101

99102
public static async Task<R> ExecuteWithAppLockAsync<R>(
100-
this (SqlConnection conn, SqlTransaction tran) context,
103+
this (SqlConnection conn, IDbTransaction tran) context,
101104
string resourceIdentifier,
102-
Func<SqlConnection, SqlTransaction, Task<R>> function
105+
Func<SqlConnection, IDbTransaction, Task<R>> function
103106
)
104107
{
105108
var lockResult = await context.conn.GetAppLockAsync(resourceIdentifier, transaction: context.tran);

src/Simpleverse.Repository.Db/SqlServer/SqlRepository.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Microsoft.Extensions.Configuration;
33
using StackExchange.Profiling.Data;
44
using System;
5+
using System.Data;
56
using System.Data.Common;
67
using System.Threading.Tasks;
78

@@ -34,12 +35,12 @@ public SqlRepository(Func<DbConnection> connectionFactory)
3435
public SqlRepository(Func<ProfiledDbConnection> connectionFactory)
3536
: base(connectionFactory) { }
3637

37-
public async Task<R> ExecuteWithAppLockAsync<R>(string resourceIdentifier, Func<DbConnection, DbTransaction, Task<R>> function)
38+
public async Task<R> ExecuteWithAppLockAsync<R>(string resourceIdentifier, Func<DbConnection, IDbTransaction, Task<R>> function)
3839
{
3940
return await ExecuteAsyncWithTransaction(
4041
async (conn, tran) =>
4142
{
42-
return await ((SqlConnection)conn, (SqlTransaction)tran).ExecuteWithAppLockAsync(resourceIdentifier, function);
43+
return await ((SqlConnection)conn, tran).ExecuteWithAppLockAsync(resourceIdentifier, function);
4344
}
4445
);
4546
}

0 commit comments

Comments
 (0)