Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 锁定Oracle行,使第二个线程无法读取数据_Sql_Multithreading_Oracle - Fatal编程技术网

Sql 锁定Oracle行,使第二个线程无法读取数据

Sql 锁定Oracle行,使第二个线程无法读取数据,sql,multithreading,oracle,Sql,Multithreading,Oracle,如何阻止一个线程的事务读取一行,直到另一个事务处理完它 我在Oracle11DB上有一个触发器表。触发器表上的一行有一个状态标志,用于指示是否需要执行某个进程,比如说触发一封电子邮件。有一个包进程定期轮询触发器表。这个过程是: 获取X个未发送状态的触发器 将X触发器的状态更新为发送 发送X封电子邮件 更新要发送的X触发器的状态 但是我在集群环境中运行我的应用程序。因此,可能有多个版本的批处理并行地下拉触发器。我希望确保相互竞争的批处理过程不会拉下相同的触发器并执行相同的处理,即发送相同的电子邮件

如何阻止一个线程的事务读取一行,直到另一个事务处理完它

我在Oracle11DB上有一个触发器表。触发器表上的一行有一个状态标志,用于指示是否需要执行某个进程,比如说触发一封电子邮件。有一个包进程定期轮询触发器表。这个过程是:

获取X个未发送状态的触发器 将X触发器的状态更新为发送 发送X封电子邮件 更新要发送的X触发器的状态 但是我在集群环境中运行我的应用程序。因此,可能有多个版本的批处理并行地下拉触发器。我希望确保相互竞争的批处理过程不会拉下相同的触发器并执行相同的处理,即发送相同的电子邮件

我正在查看Oracle SELECT FOR UPDATE子句。然而,我不是100%清楚这是否符合我的要求。我需要线程A来锁定触发器行,线程B被阻止读取或写入触发器行。如果选择更新阻止线程B读写或仅阻止线程B写,则无法100%清除。我需要前者


欢迎思考。

在PL/SQL块中,触发器也是PL/SQL块,您可以使用包。

选择更新锁并读取行。如果线程A已锁定该行,而线程B试图锁定该行,则线程B将阻塞该行,直到线程A释放其锁为止。因此,如果A和B都在执行选择更新,线程B将等待A完成

在Oracle中,读卡器从不被写卡器阻塞,因此其他线程可以自由地读取正在处理的行。他们只是无法锁定行


当然,如果您的锁定机制将应用程序转换为功能上为单线程的应用程序,那么它就违背了拥有多线程的目的。您可能需要考虑执行选择更新跳过锁定。这是一个很好的例子。

一般来说,你不能这样做。在甲骨文中,阅读永远不会被阻止。你只能阻止与你有合同的人。i、 e.另一个线程必须尝试锁定与您持有的相同的锁。无论你们是否都执行select。。对于更新或使用dbms_lock。一般来说,读卡器不会阻止写入程序,写入程序也不会阻止读卡器。@ibre5041这与下面Justin Cave的回答相矛盾。他说先选择更新锁,然后读取。我将进行测试以确认。@codelimber-纯读卡器从不阻塞。你不能阻止纯粹的选择。从严格意义上讲,SELECT FOR UPDATE不是读卡器-它必须先获得一个锁,然后才能开始读取。将SKIP锁定在一旁一段时间,如果我使用SELECT FOR UPDATE,那么线程B将能够读取行的更新前值,即使它被线程A锁定,这是我不想要的。正确吗?@CodeClimber-如果A和B都在执行“选择更新”,则操作顺序为“锁定然后读取”。如果A已锁定该行,则B通过“选择更新”锁定该行的尝试将被阻止,直到A完成。B将无法继续读取该行,直到它能够锁定该行。其他执行普通选择而不是选择更新的会话将始终能够读取行。现在获得了,谢谢。我接受你上面关于这将成为一个伪单线程解决方案的观点。我有点不同意,因为只有读取和更新触发器标志才会被阻止。在上面的示例中,发送邮件的触发器的实际处理将并行运行。