在 Hangfire 中使用锁执行 ASP.Net 代码
Using lock in Hangfire executed ASP.Net code
我在 ASP.Net MVC 项目中使用 hangfire 来管理长时间运行的后台作业。
我正在尝试使用锁定语句块进行数据库操作。这是我的锁定语句代码-
public class LockedTransaction
{
private Object thisLock = new Object();
public LockedTransaction() { }
public void UpdateCustomerBalance(long CustomerId, decimal AmountToDeduct, string ConnectionString)
{
lock (thisLock)
{
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
connection.Open();
using (SqlTransaction transaction = connection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
using (SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.Transaction = transaction;
command.CommandText = "SELECT Balance FROM Customer WHERE Id=" + CustomerId;
var userBalance = Convert.ToDecimal(command.ExecuteScalar());
userBalance = userBalance - AmountToDeduct;
command.CommandText = "UPDATE Customer SET Balance=" + userBalance + " WHERE Id=" + CustomerId;
command.ExecuteNonQuery();
transaction.Commit();
}
}
}
}
}
}
下面是我如何调用上面的代码-
foreach (var queue in queues)
{
queue.Send();
LockedTransaction lockedTransaction = new LockedTransaction();
lockedTransaction.UpdateCustomerBalance(queue.CustomerId, queue.cost, "ConnectionString");
}
问题是,数据库值没有按预期更新。比如我有5个队列如下-
queue[0].cost = 0.50;
queue[1].cost = 0.50;
queue[2].cost = 0.50;
queue[3].cost = 0.50;
queue[4].cost = 0.50;
循环完成后,数据库值应扣除2.5(总成本)。但它没有发生。有时扣除值是2.00,有时是1.5,等等
有什么建议吗?
您的锁定对象 (thisLock
) 是一个实例 属性。在 foreach
循环中,您为队列中的每个元素创建了一个 LockedTransaction
的新实例,lock
不会阻止并发执行(每次调用 UpdateCustomerBalance 方法都使用自己的锁对象)。
将 thisLock
更改为静态 属性 应该可以帮助您:
private static Object thisLock = new Object();
我在 ASP.Net MVC 项目中使用 hangfire 来管理长时间运行的后台作业。
我正在尝试使用锁定语句块进行数据库操作。这是我的锁定语句代码-
public class LockedTransaction
{
private Object thisLock = new Object();
public LockedTransaction() { }
public void UpdateCustomerBalance(long CustomerId, decimal AmountToDeduct, string ConnectionString)
{
lock (thisLock)
{
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
connection.Open();
using (SqlTransaction transaction = connection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
using (SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.Transaction = transaction;
command.CommandText = "SELECT Balance FROM Customer WHERE Id=" + CustomerId;
var userBalance = Convert.ToDecimal(command.ExecuteScalar());
userBalance = userBalance - AmountToDeduct;
command.CommandText = "UPDATE Customer SET Balance=" + userBalance + " WHERE Id=" + CustomerId;
command.ExecuteNonQuery();
transaction.Commit();
}
}
}
}
}
}
下面是我如何调用上面的代码-
foreach (var queue in queues)
{
queue.Send();
LockedTransaction lockedTransaction = new LockedTransaction();
lockedTransaction.UpdateCustomerBalance(queue.CustomerId, queue.cost, "ConnectionString");
}
问题是,数据库值没有按预期更新。比如我有5个队列如下-
queue[0].cost = 0.50;
queue[1].cost = 0.50;
queue[2].cost = 0.50;
queue[3].cost = 0.50;
queue[4].cost = 0.50;
循环完成后,数据库值应扣除2.5(总成本)。但它没有发生。有时扣除值是2.00,有时是1.5,等等
有什么建议吗?
您的锁定对象 (thisLock
) 是一个实例 属性。在 foreach
循环中,您为队列中的每个元素创建了一个 LockedTransaction
的新实例,lock
不会阻止并发执行(每次调用 UpdateCustomerBalance 方法都使用自己的锁对象)。
将 thisLock
更改为静态 属性 应该可以帮助您:
private static Object thisLock = new Object();