Hazelcast 地图被锁定时如何防止阅读
how to prevent reading when hazelcast map is locked
因为有很多数据要放入hazelcast map,我想在数据放入map的时候不让别人读取。
有什么方法可以实现吗?
例如:
map a = map(1,000,000,000) // a has 1,000,000,000 elements
map b = map(2,000) // b has 200 emlemnts
我想将所有 b 放入 a ;
b的元素应该在所有这些都放入映射a之后才能访问;
如果地图b的元素没有完全放入地图a中,则地图b的元素无法访问。
用例:
map a ={1,2,3,4,5}
map b ={a,b,c,d,e}
打印 // 结果 {1,2,3,4,5}
foreach item in b
a.put item
打印一个 // 结果 {1,2,3,4,5}
end foreach
打印一个//结果{1,2,3,4,5,a,b,c,d,e}
我想合并这两个 maps.while,在合并完成之前无法通过地图 a 访问地图 b 的元素。
我的解决方案
感谢大家的帮助。
看了hazelcast手册后,我选择了transactionalMap来解决这个问题。
transactionalMap 是 READ_COMMITED 孤立的。它可以在事务更新 map(1) 时暂停读取 map(1) 线程。
``` java
static Runnable tx = new Runnable() {
@覆盖
public无效运行(){
try {
logger.info("start transaction...");
TransactionContext txCxt = hz.newTransactionContext();
txCxt.beginTransaction();
TransactionalMap<Object, Object> map = txCxt.getMap("map");
try {
logger.info("before put map(1)");
Thread.sleep(300);
map.put("1", "1"); // reader1 is blocked
logger.info("after put map(1)");
Thread.sleep(500);
map.put("2", "2"); // reader2 is blocked
logger.info("after put map(2)");
Thread.sleep(500);
txCxt.commitTransaction();
logger.info("transaction committed");
} catch (RuntimeException t) {
txCxt.rollbackTransaction();
throw t;
}
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
logger.info("Finished testmap size:{}, testmap(1):{}, testmap(2):{} ", testmap.size(), testmap.get("1"),
testmap.get("2"));
Hazelcast.shutdownAll();
logger.info("system exit.");
System.exit(0);
}
}
};
```
您的动机/用例是什么?您可以使用事务,但这可能会对性能产生不良影响。或者,您可以使用手动锁定 - 请参阅 ILock
。
然而,当您没有机会以不同方式设计您的应用程序时,应将这两种技术用作最后的手段。
实现此目的的一种方法是在向地图 b 添加内容时锁定地图 b 中的段。将条目推送到 Map a 完成后,您可以解锁段。
尽管此方法需要 locking/unlocking.
的额外步骤,但会对性能产生影响
因为有很多数据要放入hazelcast map,我想在数据放入map的时候不让别人读取。
有什么方法可以实现吗?
例如:
map a = map(1,000,000,000) // a has 1,000,000,000 elements
map b = map(2,000) // b has 200 emlemnts
我想将所有 b 放入 a ;
b的元素应该在所有这些都放入映射a之后才能访问;
如果地图b的元素没有完全放入地图a中,则地图b的元素无法访问。
用例:
map a ={1,2,3,4,5}
map b ={a,b,c,d,e}
打印 // 结果 {1,2,3,4,5}
foreach item in b
a.put item
打印一个 // 结果 {1,2,3,4,5}
end foreach
打印一个//结果{1,2,3,4,5,a,b,c,d,e}
我想合并这两个 maps.while,在合并完成之前无法通过地图 a 访问地图 b 的元素。
我的解决方案
感谢大家的帮助。 看了hazelcast手册后,我选择了transactionalMap来解决这个问题。
transactionalMap 是 READ_COMMITED 孤立的。它可以在事务更新 map(1) 时暂停读取 map(1) 线程。
``` java static Runnable tx = new Runnable() { @覆盖 public无效运行(){
try {
logger.info("start transaction...");
TransactionContext txCxt = hz.newTransactionContext();
txCxt.beginTransaction();
TransactionalMap<Object, Object> map = txCxt.getMap("map");
try {
logger.info("before put map(1)");
Thread.sleep(300);
map.put("1", "1"); // reader1 is blocked
logger.info("after put map(1)");
Thread.sleep(500);
map.put("2", "2"); // reader2 is blocked
logger.info("after put map(2)");
Thread.sleep(500);
txCxt.commitTransaction();
logger.info("transaction committed");
} catch (RuntimeException t) {
txCxt.rollbackTransaction();
throw t;
}
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
logger.info("Finished testmap size:{}, testmap(1):{}, testmap(2):{} ", testmap.size(), testmap.get("1"),
testmap.get("2"));
Hazelcast.shutdownAll();
logger.info("system exit.");
System.exit(0);
}
}
};
```
您的动机/用例是什么?您可以使用事务,但这可能会对性能产生不良影响。或者,您可以使用手动锁定 - 请参阅 ILock
。
然而,当您没有机会以不同方式设计您的应用程序时,应将这两种技术用作最后的手段。
实现此目的的一种方法是在向地图 b 添加内容时锁定地图 b 中的段。将条目推送到 Map a 完成后,您可以解锁段。
尽管此方法需要 locking/unlocking.