Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在Hangfire中使用锁执行ASP.Net代码_Sql Server_Asp.net Mvc_Hangfire - Fatal编程技术网

Sql server 在Hangfire中使用锁执行ASP.Net代码

Sql server 在Hangfire中使用锁执行ASP.Net代码,sql-server,asp.net-mvc,hangfire,Sql Server,Asp.net Mvc,Hangfire,我正在ASP.NETMVC项目中使用hangfire来管理长时间运行的后台作业 我正在尝试使用lock语句块进行数据库操作。这是我的锁语句代码- public class LockedTransaction { private Object thisLock = new Object(); public LockedTransaction() { } public void UpdateCustomerBalance(long CustomerId, decimal

我正在ASP.NETMVC项目中使用hangfire来管理长时间运行的后台作业

我正在尝试使用lock语句块进行数据库操作。这是我的锁语句代码-

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方法都使用自己的lock对象)

将此锁更改为静态属性将有助于您:

private static Object thisLock = new Object();

谢谢你的回答。我是否应该将LockedTransaction类更改为static?@s.k.paul-如果适合您,您可以使用static/singleton类。我的主要观点是,您应该在事务中使用
one
lock对象。