【问题标题】:Concurrent Database transactions并发数据库事务
【发布时间】:2010-09-23 10:11:14
【问题描述】:

我的要求是从数据库中获取一个唯一的 ID,以便在应用程序服务器(集群应用程序)上进行处理。为此,我有一个带有单个单元格的表,其中包含一个值 X。 该值将在每次获取时递增。

BEGIN TRAN
      UPDATE ID_TABLE SET VALUE = VALUE + 1
      SELECT VALUE FROM ID_TABLE
END TRAN

考虑如下发生的两个事务(T1 和 T2)的时间表。 更新(T1),更新(T2),阅读(T1),阅读(T2)

对于数据库事务,这种交错是可能的吗?

除了在开始时获取表上的锁并在最后释放它之外,还有什么方法可以避免这种情况,这将隔离事务?

【问题讨论】:

    标签: database transactions concurrency


    【解决方案1】:

    对于数据库事务,这种交错是可能的吗?

    不,在通常的事务隔离级别,这不会发生(见下文)。

    除了获取表上的锁之外,还有什么方法可以避免这种情况

    同样,在通常的实现(例如 Oracle 的)中,您在更新行时已经锁定了行。第二个事务将阻塞其更新调用,直到第一个事务提交。此外,您不会有脏读(从其他事务中读取未提交的值)。

    如果您的数据库提供序列生成器,您可能应该使用该工具(它正是为此目的而制作的)。

    【讨论】:

    • 是不是排他行锁,在update语句后释放。那么,事务是否一直在收集锁,并且只有在完成后才释放它们?
    • 取决于事务隔离级别,我猜。但是“通常”的锁只有在你提交(或回滚)时才会释放。
    【解决方案2】:

    这由您指定的“事务隔离级别”处理。

    我不知道这在其他 DB 中是如何完成的,但是在 Sql Server(和 Access)中,您可以指定在事务启动时应该使用的隔离级别。

    选项有:

    • 读取未提交
    • 读取已提交
    • 可重复读取
    • 可序列化

    对于 SqlServer,默认隔离级别是 ReadCommitted。 这种隔离模式确保其他连接无法读取/查看任何其他未提交事务修改的数据。

    有关隔离级别的更多信息,请查看this article

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-26
      • 1970-01-01
      • 1970-01-01
      • 2016-03-29
      • 2016-06-02
      • 1970-01-01
      • 2013-11-11
      • 2023-03-15
      相关资源
      最近更新 更多