【问题标题】:Integrity and Confidentiality in Distributed Transactions分布式事务的完整性和机密性
【发布时间】:2010-05-24 11:45:56
【问题描述】:

我有一个关于分布式事务的问题。假设我有 3 个事务程序:

交易A

  1. 开始
  2. a=read(A)
  3. b=read(B)
  4. c=a+b
  5. 写(C,c)
  6. 提交

交易 B

  1. 开始
  2. a=read(A)
  3. a=a+1
  4. 写(A,a)
  5. 提交

事务 C

  1. 开始
  2. c=read(C)
  3. c=c*2
  4. 写(A,c)
  5. 提交

所以有 5 对关键操作:C2-A5、A2-B4、B4-C4、B2-C4、A2-C4。

我应该确保完整性机密性,您知道如何实现吗?

提前谢谢你!

【问题讨论】:

  • 这个例子与分布式事务无关。分布式事务是针对两个或多个数据库中的表发出 DML 的事务。
  • 另外,不确定您在这种情况下所说的“机密性”是什么意思。

标签: database security distributed-transactions distributed-system


【解决方案1】:

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

  1. 如果 Session C 在 Session A 更新后但在 Session A 提交其事务之前读取记录会发生什么情况
  2. 如果会话 C 更新了会话 A 已更新但未提交的同一记录,会发生什么情况?

(您的场景仅说明了这些问题中的第一个)。

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

  • SERIALIZABLE:从另一个会话中看不到任何更改。
  • REPEATABLE READ:允许幻读,即执行两次相同的查询可能会返回不同的结果。
  • READ COMMITTED:只有由另一个会话提交的更改才可见。
  • READ UNCOMMITTED:diryt readsallowed,即一个会话中未提交的更改在另一个会话中可见。

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    相关资源
    最近更新 更多