以下这段话来自官网:
ZooKeeper does not guarantee that at every instance in time, two different clients will have identical views of ZooKeeper data. Due to factors like network delays, one client may perform an update before another client gets notified of the change. Consider the scenario of two clients, A and B. If client A sets the value of a znode /a from 0 to 1, then tells client B to read /a, client B may read the old value of 0, depending on which server it is connected to. If it is important that Client A and Client B read the same value, Client B should should call the sync() method from the ZooKeeper API method before it performs its read.因此,如果一个组件总是需要从zk上获取最新的值时,在获取值之前应该调用sync()方法来保证当前客户端连到的zk实例的数据已和leader同步完成。但是在 org.apache.curator.framework.recipes.atomic.DistributedAtomicInteger类中,可以看到其在自增/减前从zk获取值时并没有调用sync()方法,那么是否可以认为在极端情况下,多个客户端并发对一个分布式原子数(这里的一个是指zk path相同时),会出现incr两次但是值只加了一次的情况??希望研究过zk的童鞋可以解释一下

解决方案 »

  1.   

    client.setData().withVersion(stat.getVersion()).forPath(path,newValue);这个方法才是更新操作。类似CAS操作,更新前,会检查数据的版本,如果发现数据已经被其他client更新过,则本方法会抛出异常。就是下面那个catch的 BadVersionException 异常。所以说,这个代码没有错。用sync,属于悲观锁。他这个代码不用sync,用的是CAS,属于乐观锁。如果失败,重新读取数据,再次进行更新就ok了。