有没有办法实现无锁解决方案,以确保跨多个实例的数据完整性

时间:2018-01-22 10:12:04

标签: java mysql locking data-synchronization

我正在运行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()
        }

我不确定这是否是最好的方法,如果我能以某种方式摆脱锁定,有什么建议吗?

1 个答案:

答案 0 :(得分:0)

假设您正在维护数据库的ACIDity,这些事务将彼此隔离。因此,除非您对更新的查询速度非常慢,否则无关紧要。稍后运行的查询将更新记录,并且它将保持不变。

最简单但效率最低的解决方案是将更改推送到队列中并逐个执行。这样,您可以跟踪之前完成的更改以及之后执行的更改。您还可以使用Redis的原子增量功能,您可以同时推送对该变量的更改,并且只保留最新的变量。显然,这意味着不会立即保持一致性,而只是最终的一致性。