我在具有多个节点的分布式模式下运行OrientDB(社区版2.2.9)。
几分钟后,我开始在查询中收到以下错误:
com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException: Timeout (1500ms) on acquiring lock on record #1010:2651. It is locked by request 3.1000 DB name="MyDatabase"
此实例中的查询如下所示:
UPDATE #1010:2651 SET name='foo';
记录保持锁定状态,我无法运行查询,直到我重新启动数据库。
如果我不以分布式模式运行服务器,我就不会收到此错误,因此必须与在分布式模式下运行服务器有关。
这是我的default-distributed-db-config.json
{
"autoDeploy": true,
"readQuorum": 1,
"writeQuorum": 1,
"executionMode": "asynchronous",
"readYourWrites": true,
"servers": {
"*": "master"
},
"clusters": {
"internal": {
},
"*": {
"servers": ["<NEW_NODE>"]
}
}
}
我在orientdb-server-config.xml中使用了以下配置:
....
<handler class="com.orientechnologies.orient.server.hazelcast.OHazelcastPlugin">
<parameters>
....
<parameter value="com.orientechnologies.orient.server.distributed.conflict.ODefaultReplicationConflictResolver" name="conflict.resolver.impl"/>
....
</parameters>
</handler>
...
删除&#34; ODefaultReplicationConflictResolver &#34;来自配置的参数,锁定问题的发生频率较低。
为什么记录会像这样锁定,我该如何避免?
答案 0 :(得分:3)
使用asynchronous
执行模式可能会导致此问题。请参阅:Asynchronous replication mode。
您可以尝试更改执行模式或尝试在查询中添加重试。使用Java:由于OCommandSQL的以下方法,可以在异步复制期间捕获命令事件:
onAsyncReplicationOk()
,用于在异步复制成功时捕获事件onAsyncReplicationError()
,用于在异步复制返回错误时捕获事件如果在创建边缘时出现并发修改异常,则最多重试3次:
g.command( new OCommandSQL("create edge Own from (select from User) to (select from Post)")
.onAsyncReplicationError(new OAsyncReplicationError() {
@Override
public ACTION onAsyncReplicationError(Throwable iException, int iRetry) {
System.err.println("Error, retrying...");
return iException instanceof ONeedRetryException && iRetry<=3 ? ACTION.RETRY : ACTION.IGNORE;
}
})
.onAsyncReplicationOk(new OAsyncReplicationOk() {
System.out.println("OK");
}
).execute();
或者将重试添加到SQL Batch:
begin
let upd = UPDATE #1010:2651 SET name='foo'
commit retry 100
return $upd
希望它有所帮助。