/** * Starts multi-update lock. Will wait for topology future is ready. * * @return Topology version. * @throws IgniteCheckedException If failed. */ public AffinityTopologyVersion beginMultiUpdate() throws IgniteCheckedException { IgniteBiTuple<IgniteUuid, GridDhtTopologyFuture> tup = multiTxHolder.get(); if (tup != null) throw new IgniteCheckedException("Nested multi-update locks are not supported"); top.readLock(); GridDhtTopologyFuture topFut; AffinityTopologyVersion topVer; try { // While we are holding read lock, register lock future for partition release future. IgniteUuid lockId = IgniteUuid.fromUuid(ctx.localNodeId()); topVer = top.topologyVersion(); MultiUpdateFuture fut = new MultiUpdateFuture(topVer); MultiUpdateFuture old = multiTxFuts.putIfAbsent(lockId, fut); assert old == null; topFut = top.topologyVersionFuture(); multiTxHolder.set(F.t(lockId, topFut)); } finally { top.readUnlock(); } topFut.get(); return topVer; }
/** * Ends multi-update lock. * * @throws IgniteCheckedException If failed. */ public void endMultiUpdate() throws IgniteCheckedException { IgniteBiTuple<IgniteUuid, GridDhtTopologyFuture> tup = multiTxHolder.get(); if (tup == null) throw new IgniteCheckedException("Multi-update was not started or released twice."); top.readLock(); try { IgniteUuid lockId = tup.get1(); MultiUpdateFuture multiFut = multiTxFuts.remove(lockId); multiTxHolder.set(null); // Finish future. multiFut.onDone(lockId); } finally { top.readUnlock(); } }