Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.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 2005 竞赛条件更新信用栏的修改-回滚时会发生什么?_Sql Server 2005_Transactions_Race Condition_Rollback - Fatal编程技术网

Sql server 2005 竞赛条件更新信用栏的修改-回滚时会发生什么?

Sql server 2005 竞赛条件更新信用栏的修改-回滚时会发生什么?,sql-server-2005,transactions,race-condition,rollback,Sql Server 2005,Transactions,Race Condition,Rollback,好的,我尝试过搜索,但没有找到答案-我很好奇回滚如何处理比赛条件。例如: 如果我有一个表(CompanyAccount),它跟踪一家公司有多少信用可供购买(每个公司的数据库表中只有一行),并且可能有来自同一家公司的多个用户可以从单个公司帐户中减少信用,发生回滚时发生错误时会发生什么情况 例如: 假设:我正确地编写了更新,以计算“信用”新余额,而不是猜测新的信用余额是什么(即,我们不尝试告诉更新语句新的信用余额/值是什么,我们说取信用列中的任何值,并在更新语句中减去我的递减值) 下面是如何编写up

好的,我尝试过搜索,但没有找到答案-我很好奇回滚如何处理比赛条件。例如:

如果我有一个表(CompanyAccount),它跟踪一家公司有多少信用可供购买(每个公司的数据库表中只有一行),并且可能有来自同一家公司的多个用户可以从单个公司帐户中减少信用,发生回滚时发生错误时会发生什么情况

例如:

假设:我正确地编写了更新,以计算“信用”新余额,而不是猜测新的信用余额是什么(即,我们不尝试告诉更新语句新的信用余额/值是什么,我们说取信用列中的任何值,并在更新语句中减去我的递减值)

下面是如何编写update语句的示例:

更新dbo.CompanyAccount 设置信用=信用-@DecrementAmount 其中CompanyAccountId=@CompanyAccountId

如果“学分”列有10000学分。用户A导致减少4000个信用,用户B导致减少1000个信用。出于某种原因,在用户a递减期间会触发回滚(大约有1/2打的表在事务期间插入了行)。如果用户A赢得了竞争条件,并且新的余额为6000(但尚未提交),那么如果用户B的减量发生在应用回滚之前,会发生什么情况?余额列是否从6000到5000,然后回滚到10000

我不太清楚回滚将如何处理这个问题。也许我过于简化了。有人能告诉我,如果我误解了回滚将如何工作,或者是否有其他风险,我需要担心这种风格


感谢您的输入。

在您给出的示例中,没有问题

第一个事务将具有独占锁,这意味着在第一个事务提交或回滚之前,第二个事务无法修改该行。它只需等待(阻止)直到释放锁


如果有多个语句,它会变得更复杂一些。您可能应该了解不同的隔离级别,以及它们如何允许或防止“丢失更新”等现象。

在您给出的示例中,没有问题

第一个事务将具有独占锁,这意味着在第一个事务提交或回滚之前,第二个事务无法修改该行。它只需等待(阻止)直到释放锁


如果有多个语句,它会变得更复杂一些。您可能应该了解不同的隔离级别,以及它们如何允许或防止诸如“丢失更新”之类的现象。

回滚是事务的一部分,在回滚期间将维护锁。酸中的原子。 在释放所有锁之前,用户B不会启动

发生了什么:

  • 用户A锁定行
  • 在释放锁之前,用户B不会看到这些行
  • 用户A回滚,释放锁,更改从未发生
  • 用户B可以看到这些行-1000将导致9000
但是,如果用户B已经读取了余额,那么在更新时可能不一致。这取决于您实际执行的操作以及顺序,因此需要理解(以及幻象和不可重复读取的问题)


可串行或可重复读取的替代方法可能是在事务模式下使用sp_getapplock来对事务的部分发送信号。

回滚是事务的一部分,回滚期间将保持锁。酸中的原子。 在释放所有锁之前,用户B不会启动

发生了什么:

  • 用户A锁定行
  • 在释放锁之前,用户B不会看到这些行
  • 用户A回滚,释放锁,更改从未发生
  • 用户B可以看到这些行-1000将导致9000
但是,如果用户B已经读取了余额,那么在更新时可能不一致。这取决于您实际执行的操作以及顺序,因此需要理解(以及幻象和不可重复读取的问题)

可序列化或可重复读取的替代方法可能是在事务模式下使用sp_getapplock来对事务的部分发送信号。

根据此链接()如果两个事务使用单个update语句更新行,并且更新不基于以前检索到的值,则在默认的read COMMITED隔离级别下不会发生丢失的更新。根据此链接()如果两个事务使用单个update语句更新行,并且不基于以前检索到的值进行更新,则在默认的read COMMITED隔离级别下不会发生丢失的更新。”