如何同步多台机器插入一行?

时间:2012-09-05 12:54:45

标签: oracle synchronization

我有一些代码在多台机器上运行,并访问Oracle数据库。我通过锁定行将此数据库(以及其他内容)用作不同计算机之间的同步对象。

我遇到的问题是,当我的进程启动时,数据库中还没有任何东西可以依赖于同步,并且我的进程得到关于unique constraint violated的oracle异常,因为它们都试图同时插入

我现在的解决方案是捕获该精确异常并忽略它,但我真的不喜欢在我的应用程序的正常工作流程中抛出异常。

有没有更好的方法在数据库中以原子方式“测试和插入”?插入行时锁定整个表/分区是不可接受的解决方案。

我检查merge into,认为这是我的解决方案,但它会产生同样的问题。

2 个答案:

答案 0 :(得分:4)

您可能希望使用DBMS_LOCK,它允许用户应用程序代码实现与Oracle数据库锁定行和其他资源时相同的锁定模型。您可以创建类型为'UL'(用户锁定)的队列,并定义资源名称,然后将多个会话锁定到其内容,而不依赖于某个表中的数据。它支持独占锁和共享锁,因此,您有一些可以并发运行的进程(如果它们采用共享锁)或其他独占运行的进程(如果它们采用独占锁),它们将自动在共享锁后面排队(如果有的话)由其他类型的流程等持有

这是一个非常灵活的锁定模型,您无需依赖任何表中的任何数据来实现它。

请参阅Oracle PL / SQL包和类型参考,了解DBMS_LOCK package上的完整独家新闻。

希望有所帮助。

答案 1 :(得分:2)

如果您的PK受非唯一索引监管,您不会立即收到错误,请考虑:

<<SESSION 1>>
SQL> create table afac (
  2     id number,
  3     constraint afac_pk primary key (id) 
  4        deferrable /* will cause the PK to be policed by a non-unique index */
  5  );

Table created.

SQL> insert into afac values (1);

1 row created.

<<SESSION 2>>    
SQL> insert into afac values (1); /* Will cause session 2 to be blocked */

会话2将被阻止,直到会话1提交或回滚。我不知道这种机制是否符合你的要求。