没有锁定的全局修订

时间:2015-08-07 18:14:45

标签: sql concurrency transactions locking

鉴于这套规则,是否可以在SQL中实现它?

  1. 两个不修改相同行的事务应该能够同时运行。不应发生锁定(或者至少应尽量减少其使用)。
  2. 事务只能读取已提交的数据。
  3. 修订版本定义为系统中的整数值。
  4. 新事务必须能够递增并查询新修订。此修订将应用于事务修改的每个行。
  5. 没有2个交易可以共享相同的修订。
  6. 在事务Y之前提交的事务X的版本必须低于分配给事务Y的版本。
  7. 我想使用整数作为修订版,以便优化我查询自特定修订版以来的所有更改的方式。像这样:

    SELECT * FROM [DummyTable] WHERE [DummyTable].[Revision] > clientRevision
    

    我当前的解决方案使用带有单行[LastRevision]的SQL表[GlobalRevision]来保留最新版本。我的所有交易'隔离级别设置为快照。

    此解决方案的问题是具有单行[LastRevision]的[GlobalRevision]表成为争用点。这是因为我必须在事务开始时增加修订,以便我可以将新修订应用于修改的行。这将在整个事务期间锁定[LastRevision]行,从而终止并发。即使两个并发事务修改完全不同的行,它们也不能同时执行(规则#1:失败)。

    SQL中是否有任何模式可以解决此类问题?一种解决方案是使用Guids并保留修订历史(如git修订版),但这不仅仅是一个我们可以比较的整数,以查看修订是否比另一个更新。

    更新

    此业务案例是创建一个Baas系统(后端即服务),在客户端和服务器之间进行数据同步。以下是此类系统的一些用例:

    • 在线时客户端修改资产,将更新推送到服务器,服务器更新数据库[这是我的问题与相关的位置],服务器向感兴趣的客户端发送更新通知,以便将其本地数据与新的变化。
    • 客户端连接到服务器,客户端请求拉到服务器,服务器查找客户端修订后应用的所有更改并将其返回给客户端,客户端应用更改并设置其新修订。
    • ...

    正如您所看到的,全局修订允许我对服务器上提交的每个更改进行修订,并且从此修订版中,我可以确定需要将哪些更新发送到客户端,具体取决于其特定版本。

    这需要扩展到可以并行推送更新的数千个用户,并且这些更改必须与其他连接用户同步。因此,执行事务所需的时间越长,其他用户接收更改通知所需的时间就越长。

    我想尽可能避免争用这个原因。我不是SQL的专家所以我只是想确保没有我想念的东西可以让我轻松地做到这一点。

1 个答案:

答案 0 :(得分:1)

对于您来说,最简单的方法可能是使用SEQUENCE作为您的修订号,假设您处于SQL 2012或更新版本。这是一种生成自动递增值的轻量级方法,您可以将其用作规则的修订ID。大规模获取它们应该远远少于您描述的争用问题,而不是使用完整的表格。

如果给定的事务回滚,您需要知道最终可能会出现修订号差距,因为SEQUENCE值在事务范围之外运行。来自文章:

  

序列号是在当前范围之外生成的   交易。他们是否使用该交易消费   序列号已提交或回滚。

如果您可以放宽对整数修订号的要求并确定在给定时间点知道数据是什么,那么您可以使用Change Data Capture,或者在SQL 2016中{{3 }}。这两种技术都允许您“转回时间”并查看已知时间戳下的数据。