java - 在 Berkeley DB JE 中进行比较和交换?

标签 java concurrency berkeley-db berkeley-db-je

我正在寻找一种有效的方法来在 Berkeley DB 中实现比较和交换操作。现在我使用的是非常旧的版本,但是乍一看,即使是最新的版本(从 Oracle 网站分发)也没有单一的方法来进行此类操作。

我正在寻找某种类似的方法

replace(Transaction, Key, ExpectedValue, NewValue) 

具有以下语义:DB获取与给定键关联的值,如果该值存在并且等于ExpectedValue则该值将更改为NewValue,否则方法返回不成功的OperationStatus。

似乎没有这样的方法,所以我想知道如何以最有效的方式完成此操作。

现在我正在使用以下方法:我愿意

db.get(null, key) -> {currentValue, version}
db.put(null, key, {currentValue, newRandomIdVersion}) 
db.get(null, key)

我比较值和版本,如果它们匹配,我会进行最终更新,删除旧版本。如果任何一步失败,整个过程将重新开始。

我觉得这不是最理想的 - 我错了吗?

最佳答案

我对问题的更新解决方案是错误的 - 但只需稍作修改即可使其更好。

解决方案可能如下:创建单独的数据库来存储锁,该锁将保存 key 与某个计数器的关联。该数据库应该允许排序重复项(以便 Database.get 将返回与给定键关联的最小值)。然后使用共享单调递增计数器。尝试执行 CAS 的多个线程将从该计数器获取值并将键值对存储在该锁 DB 中。存储与键关联的最低值的线程假定它有权写入并继续比较和交换所需的记录,然后从锁数据库中删除其条目,其他线程只需重试。

关于java - 在 Berkeley DB JE 中进行比较和交换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38299670/

相关文章:

database - 支持多个并发用户的文件数据库建议

java - GAE如何识别blobstore文件所有者

Java GUI - 定位

java - 最佳并发锁 : one WRITE and infinite number of READ

java - 在加入其他线程时被打断

c - 使用 C 访问 Berkeley DB 结构内的值

filesystems - fsync vs写系统调用

java - JSR082 - LocalDevice.getLocalDevice() 返回 null

java - Jersey Restful 失败,错误为 "java.lang.NoSuchMethodException: Could not find a suitable constructor"

sql - LINQ 到 SQL : Issue with concurrency