【问题标题】:Query multiple tables modified inside transaction查询事务内部修改的多个表
【发布时间】:2014-05-21 13:13:30
【问题描述】:

我有两个表 AB。我的应用程序持续执行包含以下内容的事务:

  1. 在表 B 中插入行。
  2. 更新表A中的一行。

(这两个步骤属于同一个事务,以保持表AB相互一致。)

在任何时候t,我都需要一种方法来获取表格的快照。更具体地说,在任何时候t,我需要表B中特定行的值,并且我需要插入表A中的行在上次更新表 B 行的事务期间。

例如,在时间t0,我的表格有以下内容:

表 A => (rowA1)

表 B => (rowB11, rowB12)

rowB11rowB12 已插入到将表 A 中的行更新为状态 rowA1。

在时间t1,事务再次执行,我的表现在有以下内容:

表 A => (rowA2)

表 B => (rowB11, rowB12, rowB21, rowB22)

rowB21rowB22 已插入到将表 A 中的行从状态 rowA1 移出的事务中strong> 表示 rowA2

现在,在任何时候 t,我都想选择表 A 中的行(即现在是 rowA2)并选择已插入以达到状态 rowA2 的行(即 rowB21rowB22)。我不想要的是选择表 A 中的行(即 rowA2)并获取行 rowB31rowB32 来自表 B,因为我从表 A 获得的状态与这些插入的行不匹配(刚刚在仍在运行的事务期间插入)。

我希望我的问题足够清楚。

我准确地说我正在使用 MySQL,并且我使用 Spring 管理我的事务。

谢谢, 迈克尔


编辑:

最后,仅使用事务级别至少为READ_COMMITTED 的事务是不够的。如果在两个 SELECTs 之间(一个获取表 A 中行的当前状态,另一个获取表 B 中与该状态关联的行),执行一个或多个其他事务(即执行步骤 1-2 的一个或多个),从表 B 获取的行将不对应于之前从表 获取的行的状态>一个

【问题讨论】:

    标签: java mysql transactions


    【解决方案1】:

    B 中添加一列,允许您将B 中的行与A 中的特定状态相匹配:

    时间t0

    表 A => (rowA1)
    表 B => (rowB11, rowA1), (rowB12, rowA1)

    时间t1

    表 A => (rowA2)
    表 B => (rowB11, null), (rowB12, null), (rowB21, rowA2), (行B22,行A2)

    t1,您想要的 B 中的行类似于 SELECT * FROM B WHERE ref_to_A = [current_value_in_A]


    毕竟,您的问题似乎与事务隔离有关。所以我们开始吧:

    事务期间发生的任何事情(除非隔离级别为READ_UNCOMMITTED),即在BEGINCOMMIT(或ROLLBACK)之间,对并发事务都是不可见的。

    【讨论】:

    • 感谢您的回复。已经有一个外键,但它没有帮助,因为该行总是更新,因此外键总是指向同一行。
    • 为每个状态更改将行插入 A 是有问题的,因为更改发生得非常频繁。
    • 好吧,“外键”是不恰当的名称,但绝对是从 BA 的引用,您可以使用它来区分 B 中的行。
    • 直到现在,我认为在一个隔离级别至少为 READ_COMMITTED 的事务中执行两个 SELECT 就足够了,但我不确定。
    • 如果事物包含在事务中(除非 READ_UNCOMMITTED),那么在 BEGINCOMMIT 之间发生的任何事情对并发事务都是不可见的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-13
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    相关资源
    最近更新 更多