我有一个进程可以在表中查询PROCESS_IND
='N'的记录,进行一些处理,然后将PROCESS_IND
更新为'Y'。
我想允许运行此进程的多个实例,但不知道避免并发问题的最佳实践是什么。
我应该从哪里开始?
答案 0 :(得分:10)
我使用的模式如下:
每项任务都会执行以下查询:
UPDATE taskstable SET lockedby =(我的id),locktime = now()WHERE lockedby IS NULL ORDER BY ID LIMIT 10
其中10是“批量大小”。
LIMIT 10是MySQL特定的,但我认为其他数据库具有等价物。导入ORDER BY是为了避免查询不确定。
答案 1 :(得分:4)
虽然我明白了我不同意立即进行行级别锁定的意图。这会缩短您的响应时间,实际上可能会使您的情况变得更糟。如果在测试之后您看到APL的并发问题,您应该首先迭代移动到“datapage”锁定!
要真正回答这个问题,需要更多关于表格结构和所涉索引的信息,但需要进一步解释。
DOL,数据行锁定比全页/页面级锁定使用更多的锁。管理所有锁的开销以及由于缓存中更多锁结构的请求而导致的可用内存减少将降低性能,并通过转向更加并发的方法来抵消任何增益。
测试您的方法而不首先在APL上移动(所有页面锁定'默认')然后如果看到问题移动到DOL(数据页首先然后是数据行)。请记住,当您将表格切换到DOL时,该表格上的所有响应都会变得更糟,表格会占用更多空间,而且表格更容易碎片化,需要定期维护。
所以总之不要直接转到datarows尝试你的并发方法然后如果有问题首先使用datapage锁定然后使用最后的数据行。
答案 2 :(得分:2)
您应该在表格中启用row level locking
:
CREATE TABLE mytable (...) LOCK DATAROWS
然后你:
FOR UPDATE
选项的行(将锁定它)在交易结束之前,没有其他进程可以对此行执行任何操作。
P上。 S. 有人提到使用LOCK DATAROWS
可能导致的开销问题。
是的,有开销,但我很难称这是一个像这样的桌子的问题。
但是如果切换到DATAPAGES
,那么每个PAGE
(默认情况下为2k
)只能锁定一行,并且其行位于一个页面中的进程将无法运行同时进行。
如果我们谈论的桌子会同时锁定十几行,那么几乎不会出现明显的性能下降。
流程并发对于这样的设计来说更为重要。
答案 3 :(得分:1)
最明显的方法是锁定,如果您的数据库没有锁,您可以通过添加“锁定”字段来自己实现。
简化并发性的一些方法是随机化对未处理项的访问,因此它们不是在第一项上竞争,而是随机分配访问权。
答案 4 :(得分:0)
将过程转换为单个SQL语句,并将多个行作为单个批处理。这就是数据库的工作方式。