这是令人难以置信的沮丧…我正在使用Couchbase v3 C API,我遇到了一个问题,这个问题可以通过使用他们的“悲观”锁定来完美解决。经过一番努力,我相信我终于找到了如何使用它锁定记录(使用lcb_cmdget_locktime()
,它大概需要一个以微秒为单位的参数),但是我不知道如何在完成后解锁记录,除了让它超时,这不是一个可以接受的解决方案。
这里的文档提供了一个示例,但出于某种未知的原因,它使用的是Javascript而不是C(!!!),并且这些概念没有映射到C API。
有人知道如何解锁悲观锁吗,或者有使用该API的示例C/C代码吗?除此之外,有人知道在哪里可以找到使用C语言的任何非C API的源代码吗?(我也找不到其中的任何一个,不确定它们是开源的。)
谢谢你的提问
以秒为单位的时间,请注意,如果时间大于最大时间,服务器可能会将时间重置为默认值(两个持续时间都是可配置的)。以下命令将有助于发现特性的有效值。
$ cbstats -u Administrator -p password localhost all | grep ep_getl
ep_getl_default_timeout: 15
ep_getl_max_timeout: 30
要锁定密钥,必须使用 get 操作并使用 lcb_cmdget_locktime
设置锁定时间,并在成功锁定的情况下捕获 CAS 值,例如这样
struct my_result {
lcb_STATUS status{LCB_SUCCESS};
uint64_t cas{0};
};
static void get_callback(lcb_INSTANCE *instance, lcb_CALLBACK_TYPE, const lcb_RESPGET *resp)
{
my_result *res = nullptr;
lcb_respget_cookie(resp, (void **)&res);
res->status = lcb_respget_status(resp);
if (res->status == LCB_SUCCESS) {
lcb_respget_cas(resp, &res->cas);
}
}
将带有锁代码的获取放入循环中是个好主意
uint64_t locked_cas{0};
int retries = 3;
while (retries > 0) {
std::string document_id{"foo"};
my_result result{};
lcb_CMDGET* cmd = nullptr;
lcb_cmdget_create(&cmd);
lcb_cmdget_key(cmd, document_id.c_str(), document_id.size());
lcb_cmdget_locktime(cmd, 5);
lcb_get(instance, &result, cmd);
lcb_cmdget_destroy(cmd);
lcb_wait(instance, LCB_WAIT_DEFAULT);
if (result.rc == LCB_SUCCESS) {
locked_cas = result.cas;
break;
} else if (result.rc == LCB_ERR_DOCUMENT_LOCKED || result.rc == LCB_ERR_TEMPORARY_FAILURE) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
--retries;
continue;
} else {
std::cerr << "Unexpected issue during get with lock: " << lcb_strerror_short(result.rc) << "\n";
break;
}
}
一旦键被锁定,就可以执行更新操作,但请记住,它必须使用locked_cas
,否则变异操作将失败。
std::string document_id{"foo"};
std::string new_value{"new value"};
lcb_CMDSTORE* cmd = nullptr;
lcb_cmdstore_create(&cmd, LCB_STORE_REPLACE);
lcb_cmdstore_key(cmd, document_id.c_str(), document_id.size());
lcb_cmdstore_value(cmd, new_value.c_str(), new_value.size());
lcb_cmdstore_cas(cmd, locked_cas);
lcb_store(instance, nullptr, cmd);
lcb_cmdstore_destroy(cmd);
lcb_wait(instance, LCB_WAIT_DEFAULT);
要解锁密钥,您还需要locked_cas
,或者等到服务器自动解锁文档。
std::string document_id{"foo"};
lcb_CMDUNLOCK *cmd = nullptr;
lcb_cmdunlock_create(&cmd);
lcb_cmdunlock_key(cmd, document_id.c_str(), document_id.size());
lcb_cmdunlock_cas(cmd, locked_cas);
lcb_unlock(instance, nullptr, cmd);
lcb_cmdunlock_destroy(cmd);
lcb_wait(instance, LCB_WAIT_DEFAULT);
问题内容: 我正在使用Criteria API检索hibernate中的对象列表。但是,我需要锁定那些对象,因为同时执行的另一个线程将获得确切的对象,并且在没有悲观锁定的情况下,只有一个线程会成功。 我尝试如下,但它不起作用。 更新 :我正在执行此语句之后的更新,以便我希望两个线程都读取不同的行,或者至少第二个线程应该等到第一个线程完成事务并离开锁。 hibernate生成的查询如下。 更新 :这
编辑:在这种情况下,因为我使用了“版本”注释,所以我使用了乐观锁定,而不是悲观锁定。< br >如果我删除版本并因此禁用乐观锁定。悲观锁定会接管,性能会显著下降。< br >所以我想我必须忍受乐观锁定和偶尔的异常。有没有更好的解决办法? 原文:我目前通过ajp在apache 2.2负载均衡器中有多个Tomcat实例。后端系统处于Hibernate状态。该系统为多个用户和请求提供服务,对于请求,它会
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作 乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。 乐观锁与悲观锁的具体区别: http://www.cnblogs.com/Bob-FD/p/3352216.html
问题内容: 我在java下有spring项目,使用hibernate查询,我喜欢使用悲观锁定。 在Spring + Hibernate中如何进行悲观锁定? 编辑: 问题: 我想在一个方法中使用悲观锁定,并且我将此方法称为从不同的方法。当我从第一个方法调用它时,悲观的工作效果很好,但是当我从第二个方法调用它时,它给出了(无法提交事务) 例外: 问题答案: http://www.amicabile.c
我上面代码的日志是: 数据库也会更新。为什么lock()不工作?不是在lock()之后其他实例无法更新吗?还是别的什么?还是我错过了什么?
本文向大家介绍说一下乐观锁和悲观锁?相关面试题,主要包含被问及说一下乐观锁和悲观锁?时的应答技巧和注意事项,需要的朋友参考一下 乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。 悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻止,直到这个锁被释放。 数据库的乐观锁需要自