【发布时间】:2018-02-06 10:05:45
【问题描述】:
这个问题是关于优化的。 有问题的场景如下:
我有一个表,其中包含多个事务应读取和执行的数据。该表由三列组成:{id, message, status}。
ID MESSAGE STATUS
1 First Message NEW
2 Second Message MOD
3 Third Message FIN
....
如图所示,状态是以下三种状态之一:{new, mod, fin}。它们指示一行是新的、此时正在处理还是已成功处理。 我这样做是为了让多个事务在这个表上工作。事务读取所有“新”消息并将状态更改为“MOD”,以指示它们正在被处理并锁定它们。之后,它们被处理。成功处理的行将设置为“FIN”,失败的行将设置为“NEW”,以便下一个事务将再次尝试这些。
除了状态的改变,该表是只读的。要处理的准确信息永远不会改变。
上述过程有效,但我认为它不必要地复杂。我在这里寻找的是一个更简单的解决方案。我已经阅读了不同的隔离级别,但它们基本上都会导致行以某种方式被锁定,以便其他事务必须等待。我不想要那个。相反,我希望那些已经读取的行被其他查询忽略。
现在终于来了一个问题: 是否可以在读取时锁定行,以便它们将被其他事务忽略,而不是等待这些行被解锁的事务?
我想要这样的东西: 假设该表包含 30 行。
- 事务“reader1”读取 30 行,(id 1-30)。这些行现在已锁定(最好对其他人不可见)。
- 事务“writer”插入 20 个新行。 (id 31-50)
- 此时,“reader1”尚未完成。无需等待“reader1”完成,事务“reader2”只读取新的 20 行,因为其他行(1-30)被“reader1”隐藏
- “reader1”和“reader2”完成。它们完成的顺序无关紧要,因为它们处理分离的数据集。
有没有办法在不需要状态栏的情况下做到这一点?
- 使用的 DBMS 是 IBM 的 DB2
- 通过 ODBC 访问
【问题讨论】:
-
您使用的是哪个 dbms?为什么一个用户读取的行对其他用户是不可见的?
-
这可能取决于您使用的 DBMS,以及它如何处理锁争用(有各种策略,例如脏读、最后一次清读等),这些通常可以配置。然而,这超出了关系理论甚至 SQL 标准,并且将是特定于实现的。
-
@jarlh 我添加了一些信息。我想这样做,以便每一行只处理一次,这样我就不必让我的状态表明当时正在处理哪一行。我想尽量减少写作和阅读。
-
@Rags 添加到问题中,DBMS 是 DB2
-
添加 Db2 服务器(Z/os、i 系列、Linux/Unix/Windows)的平台和 Db2 的版本 -服务器软件。
标签: sql database multithreading transactions db2