2011-09-19 26 views
3

通过分布式缓存产品,我的意思是像Coherence或Hazelcast。我将以Hazelcast为例。如何传送在分布式缓存产品中的多个分布式映射上运行的事务

假设我有,保持在许多地图的状态的对象:

class DataState { 
    Map<ID, Dog> dogs = Hazelcast.getMap("dog"); 
    Map<ID, Owner> owners = Hazelcast.getMap("owner"); 

    public void associate(Dog dog, Owner owner) { 
      /* ... put in maps and set up references */ 
    } 
} 

注意,联想()函数需要是事务性的,因为它修改多个地图。由于狗和所有者在某种程度上是相关联的,因此可能数据在方法完成之前处于不一致的状态。现在,如果另一个类从分布式内存中读取,它不知道事务正在发生,并且可能会看到数据不一致。

class DataStateClient { 
    Map<ID, Dog> dogs = Hazelcast.getMap("dog"); 
    Map<ID, Owner> owners = Hazelcast.getMap("owner"); 

    public void doSomething() { 
     // oops, owner2 is associated with dog1 but 
     // dog1 is not yet in the map! 
    } 
} 

现在,Hazelcast已经分配了锁来解决类似的问题,但是性能影响是什么?假设doSomething()是昂贵的(例如,在本地复制两个映射),在这种情况下,它可能不足以锁定多个客户端。

是否有这种分布式同步问题的标准解决方案?

+1

是锁坏..所以做交易。可以订购解决这个特定的问题;先将dog1放入地图中,然后创建关联?因此,相关的dog1将始终在地图中。 –

回答

1

如果要序列化写入访问(互斥),分布式锁定是一种方法。如果您使用Cacheonix,则使用Cacheonix读/写锁时,您的示例可能会有更好的性能。该读者的方式可以有并发读访问,不会有等待一台服务器来完成,这将是如果使用一个简单的互斥体的情况下:

编剧:

final Cacheonix cacheonix = Cacheonix.getInstance(); 
    final ReadWriteLock rwLock = cacheonix.getCluster().getReadWriteLock(); 
    final Lock writeLock = rwLock.writeLock(); 
    writeLock.lock(); 
    try { 
    // No one else can enter this section 

    // Update dogs 

    // Update owners 
    } finally { 
    writeLock.unlock(); 
    } 

...

读者:

final Cacheonix cacheonix = Cacheonix.getInstance(); 
    final ReadWriteLock rwLock = cacheonix.getCluster().getReadWriteLock(); 
    final Lock readLock = rwLock.readLock(); 
    readLock.lock(); 
    try { 
    // Readers can enter this section simultaneously 

    // Read dogs 

    // Read owners 
    } finally { 
    readLock.unlock(); 
    }