分布式事务中的完整性和机密性

时间:2010-05-24 11:45:57

标签: database security distributed-transactions distributed-system

我对分布式交易有疑问。假设我有3个交易程序:

交易A

  1. 开始
  2. A =读(A)
  3. B =读(B)
  4. C = A + B
  5. 写(C,C)
  6. 提交
  7. 交易B

    1. 开始
    2. A =读(A)
    3. A = A + 1
    4. 写(A,A)
    5. 提交
    6. 交易C

      1. 开始
      2. C =读(C)
      3. C = C * 2
      4. 写(A,C)
      5. 提交
      6. 因此有5对关键操作:C2-A5,A2-B4,B4-C4,B2-C4,A2-C4。

        我应该确保诚信机密性,您对如何实现它有任何想法吗?

        提前谢谢!

1 个答案:

答案 0 :(得分:0)

您在帖子中描述的内容是多用户系统中的常见情况。不同的会话使用相同的表并且实际上相同的行同时启动事务。这里有两个问题:

  1. 如果会话C在会话A更新之后读取记录会发生什么,但在会话A提交其交易之前会发生什么?
  2. 如果会话C更新了会话A已更新但未提交的相同记录,会发生什么?
  3. (您的方案仅说明了第一个问题)。

    第一个问题的答案是ioslation level。这是跨会话的未提交事务的可见性的定义。 ANSI standard specifies four levels

    • SERIALIZABLE:无法看到其他会话的更改。
    • REPEATABLE READ:允许幻像读取,即执行两次相同的查询可能会返回不同的结果。
    • READ COMMITTED:只显示另一个会话提交的更改。
    • READ UNCOMMITTED:diryt readallowed,即一个会话中未提交的更改在另一个会话中可见。

    不同的口味或数据库以不同的方式实现这些,并非所有数据库都支持所有这些。例如,Oracle仅支持READ COMMITTED和SERIALIZABLE,并且它将SERIALIZABLE实现为snapsot(即它是只读事务)。但是,它使用多版本并发控制来防止READ COMMITTED事务中的不可重复读取。

    所以,回到你的问题,答案是:设置适当的隔离级别。适当的级别取决于数据库支持的级别以及您希望发生的行为。您可能想要READ COMMITTED或SERIALIZABLE,也就是说您希望您的交易基于与交易开始一致的数据值继续进行。

    至于另一个问题,答案更简单:在开始更新表之前,事务必须在表上或最好只是所需的行上发出锁。这可确保事务可以继续更改这些值而不会导致死锁。这称为悲观锁定。在使用连接池的应用程序(即大多数基于Web的应用程序)中,这是不可能的,并且情况有很多。