/** * @param nodeId Node ID. * @param res Response. */ private void processFinishResponse(UUID nodeId, GridNearTxFinishResponse<K, V> res) { GridNearTxFinishFuture<K, V> fut = (GridNearTxFinishFuture<K, V>) ctx.mvcc().<GridCacheTx>future(res.xid().id(), res.futureId()); if (fut == null) { if (log.isDebugEnabled()) log.debug( "Failed to find future for finish response [sender=" + nodeId + ", res=" + res + ']'); return; } fut.onResult(nodeId, res); }
/** {@inheritDoc} */ @Override public void rollback() throws GridException { GridNearTxPrepareFuture<K, V> prepFut = this.prepFut.get(); GridNearTxFinishFuture<K, V> fut = rollbackFut.get(); if (fut == null && !rollbackFut.compareAndSet( null, fut = new GridNearTxFinishFuture<K, V>(cctx, this, false))) { rollbackFut.get(); return; } try { cctx.mvcc().addFuture(fut); if (prepFut == null) { finish(false); fut.finish(); } else { prepFut.listenAsync( new CI1<GridFuture<GridCacheTxEx<K, V>>>() { @Override public void apply(GridFuture<GridCacheTxEx<K, V>> f) { try { // Check for errors in prepare future. f.get(); } catch (GridException e) { if (log.isDebugEnabled()) log.debug("Got optimistic tx failure [tx=" + this + ", err=" + e + ']'); } try { finish(false); rollbackFut.get().finish(); } catch (GridException e) { U.error(log, "Failed to gracefully rollback transaction: " + this, e); rollbackFut.get().onError(e); } } }); } // TODO: Rollback Async? fut.get(); } catch (Error e) { U.addLastCause(e, commitErr.get()); throw e; } catch (RuntimeException e) { U.addLastCause(e, commitErr.get()); throw e; } catch (GridException e) { U.addLastCause(e, commitErr.get()); throw e; } finally { cctx.tm().txContextReset(); cctx.near().dht().context().tm().txContextReset(); } }