我正在运行java应用程序的多个实例,并且所有这些实例都连接到一个mysql数据库,我遇到了一个问题,我有一些数据(数字),我想确保它的完整性。
例如,我在实例A上收到一个请求,说该值应该增加5,同时实例B上的另一个请求将值递增1,依此类推......
我一直在研究我的问题的不同实现,到目前为止所有这些都使用了某种锁定机制,例如这段代码就是我现在所拥有的。
protected Lock getLock(String seqName) {
Lock oldLock, dbSequenceLock = dbSequenceLocks.get(seqName)
if (dbSequenceLock == null) {
dbSequenceLock = new ReentrantLock()
oldLock = dbSequenceLocks.putIfAbsent(seqName, dbSequenceLock)
if (oldLock != null) return oldLock
}
return dbSequenceLock
}
protected String update(String seqName, int value) {
try{
Lock dbSequenceLock = getDbSequenceLock(seqName)
dbSequenceLock.lock()
Type record = selectForUpdate(seqName);//This selects the
entity for update
record.set("val", record.get("val") + val);//increment or decrement the value...
record.update();
} finally {
dbSequenceLock.unlock()
}
我不确定这是否是最好的方法,如果我能以某种方式摆脱锁定,有什么建议吗?
答案 0 :(得分:0)
假设您正在维护数据库的ACIDity,这些事务将彼此隔离。因此,除非您对更新的查询速度非常慢,否则无关紧要。稍后运行的查询将更新记录,并且它将保持不变。
最简单但效率最低的解决方案是将更改推送到队列中并逐个执行。这样,您可以跟踪之前完成的更改以及之后执行的更改。您还可以使用Redis的原子增量功能,您可以同时推送对该变量的更改,并且只保留最新的变量。显然,这意味着不会立即保持一致性,而只是最终的一致性。