public void updateRecord(MetaRecord rec) { try { long ts = System.currentTimeMillis(); putRecord(rec, ts); String node = ZKUtil.joinZNode(H2MetaTableTracker.NODE_NAME, Integer.toString(rec.getId())); // setData会异步触发所有机器(包括本机)上的H2MetaTableTracker.nodeDataChanged // 然后触发下列调用: // =>org.h2.engine.Database.updateDatabaseObject(int) // =>org.h2.engine.Database.update(Session, DbObject) // =>org.h2.engine.Database.addMeta0(Session, DbObject, boolean) // =>又到此方法 // 所以会造成循环 synchronized (this) { // 避免setData后立刻触发nodeDataChanged,此时IdVersion还未更新 ZKUtil.setData(watcher, node, Bytes.toBytes(ts)); // setData后watch不见了,所以要继续watch,监听其他人对此node的修改 // ZKUtil.watchAndCheckExists(watcher, node); Stat stat = new Stat(); ZKUtil.getDataAndWatch(watcher, node, stat); // 这里记录下id的最新版本,触发nodeDataChanged时再检查一下是否版本一样, // 如果不大于这里的版本那么就不再执行updateDatabaseObject操作 tracker.updateIdVersion(rec.getId(), stat.getVersion()); } } catch (Exception e) { throw new RuntimeException(e); } }
public void addRecord(MetaRecord rec) { try { putRecord(rec, System.currentTimeMillis()); String node = ZKUtil.joinZNode(H2MetaTableTracker.NODE_NAME, Integer.toString(rec.getId())); ZKUtil.createAndWatch(watcher, node, EMPTY_BYTE_ARRAY); tracker.updateIdVersion(rec.getId(), 0); } catch (Exception e) { throw new RuntimeException(e); } }
public void loadMetaRecords(List<MetaRecord> records) throws Exception { MetaRecord rec; for (Result r : table.getScanner(new Scan())) { if (r.isEmpty()) continue; rec = getMetaRecord(r); records.add(rec); if (!tracker.contains(rec.getId())) ZKUtil.createNodeIfNotExistsAndWatch( watcher, ZKUtil.joinZNode(H2MetaTableTracker.NODE_NAME, Integer.toString(rec.getId())), EMPTY_BYTE_ARRAY); } }
private void putRecord(MetaRecord rec, long ts) throws Exception { Put put = new Put(Bytes.toBytes(rec.getId())); put.add(FAMILY, OBJECT_TYPE, ts, Bytes.toBytes(rec.getObjectType())); put.add(FAMILY, SQL, ts, Bytes.toBytes(rec.getSQL())); // System.out.println("addRecord id: " + rec.getId() + ", sql=" + rec.getSQL()); table.put(put); }