public TephraTransactionContext(byte[] txnBytes) throws IOException { this(); this.tx = CODEC.decode(txnBytes); }
private Transaction getCurrentTransaction() { return tx != null ? tx : txContext != null ? txContext.getCurrentTransaction() : null; }
void addTransactionAware(TransactionAware txAware) { if (this.txContext != null) { txContext.addTransactionAware(txAware); } else if (this.tx != null) { txAwares.add(txAware); assert (tx != null); txAware.startTx(tx); } }
private void commit() throws TransactionFailureException { try { txClient.commitOrThrow(currentTx); } catch (TransactionFailureException e) { abort(e); // abort will rethrow this exception } catch (Throwable e) { String message = String.format("Exception from commit for transaction %d.", currentTx.getTransactionId()); abort(new TransactionFailureException(message, e)); // abort will throw that exception } }
@Override public long getWritePointer() { Transaction tx = getCurrentTransaction(); return tx == null ? HConstants.LATEST_TIMESTAMP : tx.getWritePointer(); }
@Override public PhoenixTransactionClient getTransactionClient(Configuration config, ConnectionInfo connectionInfo) { if (connectionInfo.isConnectionless()) { TransactionManager txnManager = new TransactionManager(config); TransactionSystemClient txClient = new InMemoryTxSystemClient(txnManager); return new TephraTransactionClient(txClient); ZKClients.reWatchOnExpire( ZKClients.retryOnFailure( new TephraZKClientService(zkQuorumServersString, timeOut, null, ArrayListMultimap.<String, byte[]>create()), RetryStrategies.exponentialDelay(500, retryTimeOut, TimeUnit.MILLISECONDS)) PooledClientProvider pooledClientProvider = new PooledClientProvider( config, zkDiscoveryService); TransactionServiceClient txClient = new TransactionServiceClient(config,pooledClientProvider); TephraTransactionClient client = new TephraTransactionClient(zkClientService, txClient); client.start();
@Override public PhoenixTransactionService getTransactionService(Configuration config, ConnectionInfo connInfo, int port) { config.setInt(TxConstants.Service.CFG_DATA_TX_BIND_PORT, port); int retryTimeOut = config.getInt(TxConstants.Service.CFG_DATA_TX_CLIENT_DISCOVERY_TIMEOUT_SEC, TxConstants.Service.DEFAULT_DATA_TX_CLIENT_DISCOVERY_TIMEOUT_SEC); ZKClientService zkClient = ZKClientServices.delegate( ZKClients.reWatchOnExpire( ZKClients.retryOnFailure( ZKClientService.Builder.of(connInfo.getZookeeperConnectionString()) .setSessionTimeout(config.getInt(HConstants.ZK_SESSION_TIMEOUT, HConstants.DEFAULT_ZK_SESSION_TIMEOUT)) .build(), RetryStrategies.exponentialDelay(500, retryTimeOut, TimeUnit.MILLISECONDS) ) ) ); DiscoveryService discovery = new ZKDiscoveryService(zkClient); TransactionManager txManager = new TransactionManager(config, new HDFSTransactionStateStorage(config, new SnapshotCodecProvider(config), new TxMetricsCollector()), new TxMetricsCollector()); TransactionService txService = new TransactionService(config, zkClient, discovery, Providers.of(txManager)); TephraTransactionService service = new TephraTransactionService(zkClient, txService); service.start(); return service; }
@Override public long getTransactionId() { Transaction tx = getCurrentTransaction(); return tx == null ? HConstants.LATEST_TIMESTAMP : tx.getTransactionId(); // First write pointer - won't change with checkpointing }
@Override public void abort() throws SQLException { if (txContext == null || !isTransactionRunning()) { return; } try { txContext.abort(); } catch (TransactionFailureException e) { throw new SQLExceptionInfo.Builder( SQLExceptionCode.TRANSACTION_FAILED) .setMessage(e.getMessage()).setRootCause(e).build() .buildException(); } }
@Override public void begin() throws SQLException { if (txContext == null) { throw new SQLExceptionInfo.Builder( SQLExceptionCode.NULL_TRANSACTION_CONTEXT).build() .buildException(); } try { txContext.start(); } catch (TransactionFailureException e) { throw new SQLExceptionInfo.Builder( SQLExceptionCode.TRANSACTION_FAILED) .setMessage(e.getMessage()).setRootCause(e).build() .buildException(); } }
@Override public void commit() throws SQLException { if (txContext == null || !isTransactionRunning()) { return; } try { txContext.finish(); } catch (TransactionFailureException e) { if (e instanceof TransactionConflictException) { throw new SQLExceptionInfo.Builder( SQLExceptionCode.TRANSACTION_CONFLICT_EXCEPTION) .setMessage(e.getMessage()).setRootCause(e).build() .buildException(); } throw new SQLExceptionInfo.Builder( SQLExceptionCode.TRANSACTION_FAILED) .setMessage(e.getMessage()).setRootCause(e).build() .buildException(); } }
@Override public byte[] encodeTransaction() throws SQLException { Transaction tx = getCurrentTransaction(); assert (tx != null); try { byte[] encodedTxBytes = CODEC.encode(tx); encodedTxBytes = Arrays.copyOf(encodedTxBytes, encodedTxBytes.length + 1); encodedTxBytes[encodedTxBytes.length - 1] = getProvider().getCode(); return encodedTxBytes; } catch (IOException e) { throw new SQLException(e); } }
@Override public void checkpoint(boolean hasUncommittedData) throws SQLException { if (hasUncommittedData) { try { if (txContext == null) { tx = txServiceClient.checkpoint(tx); } else { assert (txContext != null); txContext.checkpoint(); tx = txContext.getCurrentTransaction(); } } catch (TransactionFailureException e) { throw new SQLException(e); } } // Since we're querying our own table while mutating it, we must exclude // see our current mutations, otherwise we can get erroneous results // (for DELETE) // or get into an infinite loop (for UPSERT SELECT). if (txContext == null) { tx.setVisibility(VisibilityLevel.SNAPSHOT_EXCLUDE_CURRENT); } else { assert (txContext != null); txContext.getCurrentTransaction().setVisibility( VisibilityLevel.SNAPSHOT_EXCLUDE_CURRENT); } }
public TephraTransactionContext(PhoenixConnection connection) throws SQLException { PhoenixTransactionClient client = connection.getQueryServices().initTransactionClient(getProvider()); assert (client instanceof TephraTransactionClient); this.txServiceClient = ((TephraTransactionClient)client).getTransactionClient(); this.txAwares = Collections.emptyList(); this.txContext = new TransactionContext(txServiceClient); }
@Override public PhoenixVisibilityLevel getVisibilityLevel() { VisibilityLevel visibilityLevel = null; Transaction tx = getCurrentTransaction(); assert(tx != null); visibilityLevel = tx.getVisibilityLevel(); PhoenixVisibilityLevel phoenixVisibilityLevel; switch (visibilityLevel) { case SNAPSHOT: phoenixVisibilityLevel = PhoenixVisibilityLevel.SNAPSHOT; break; case SNAPSHOT_EXCLUDE_CURRENT: phoenixVisibilityLevel = PhoenixVisibilityLevel.SNAPSHOT_EXCLUDE_CURRENT; break; case SNAPSHOT_ALL: phoenixVisibilityLevel = PhoenixVisibilityLevel.SNAPSHOT_ALL; default: phoenixVisibilityLevel = null; } return phoenixVisibilityLevel; }
FenceWait fenceWait = VisibilityFence.prepareWait(key, txServiceClient); fenceWait.await(10000, TimeUnit.MILLISECONDS); + getCurrentTransaction().getReadPointer());
@Override public long getReadPointer() { Transaction tx = getCurrentTransaction(); if (tx == null) { return (-1); } return tx.getReadPointer(); }
@Override public void markDMLFence(PTable table) { if (table.getType() == PTableType.INDEX) { return; } byte[] logicalKey = table.getName().getBytes(); TransactionAware logicalTxAware = VisibilityFence.create(logicalKey); if (this.txContext == null) { this.txAwares.add(logicalTxAware); } else { this.txContext.addTransactionAware(logicalTxAware); } byte[] physicalKey = table.getPhysicalName().getBytes(); if (Bytes.compareTo(physicalKey, logicalKey) != 0) { TransactionAware physicalTxAware = VisibilityFence .create(physicalKey); if (this.txContext == null) { this.txAwares.add(physicalTxAware); } else { this.txContext.addTransactionAware(physicalTxAware); } } }
@Override public void join(PhoenixTransactionContext ctx) { if (ctx == PhoenixTransactionContext.NULL_CONTEXT) { return; } assert (ctx instanceof TephraTransactionContext); TephraTransactionContext tephraContext = (TephraTransactionContext) ctx; if (txContext != null) { for (TransactionAware txAware : tephraContext.getAwares()) { txContext.addTransactionAware(txAware); } } else { txAwares.addAll(tephraContext.getAwares()); } }
@Override public void setVisibilityLevel(PhoenixVisibilityLevel visibilityLevel) { VisibilityLevel tephraVisibilityLevel = null; switch (visibilityLevel) { case SNAPSHOT: tephraVisibilityLevel = VisibilityLevel.SNAPSHOT; break; case SNAPSHOT_EXCLUDE_CURRENT: tephraVisibilityLevel = VisibilityLevel.SNAPSHOT_EXCLUDE_CURRENT; break; case SNAPSHOT_ALL: tephraVisibilityLevel = VisibilityLevel.SNAPSHOT_ALL; break; default: assert (false); } Transaction tx = getCurrentTransaction(); assert(tx != null); tx.setVisibility(tephraVisibilityLevel); }