@Override public TransactionId beginTransaction(IsolationLevel isolationLevel, boolean readOnly, boolean autoCommitContext) { TransactionId transactionId = TransactionId.create(); BoundedExecutor executor = new BoundedExecutor(finishingExecutor, maxFinishingConcurrency); TransactionMetadata transactionMetadata = new TransactionMetadata(transactionId, isolationLevel, readOnly, autoCommitContext, catalogManager, executor); checkState(transactions.put(transactionId, transactionMetadata) == null, "Duplicate transaction ID: %s", transactionId); return transactionId; }
.collect(toList())); addExceptionCallback(future, throwable -> { abortInternal(); log.error(throwable, "Read-only connector should not throw exception on commit"); });
private synchronized void cleanUpExpiredTransactions() { Iterator<Entry<TransactionId, TransactionMetadata>> iterator = transactions.entrySet().iterator(); while (iterator.hasNext()) { Entry<TransactionId, TransactionMetadata> entry = iterator.next(); if (entry.getValue().isExpired(idleTimeout)) { iterator.remove(); log.info("Removing expired transaction: %s", entry.getKey()); entry.getValue().asyncAbort(); } } }
private synchronized CatalogMetadata getTransactionCatalogMetadata(ConnectorId connectorId) { checkOpenTransaction(); CatalogMetadata catalogMetadata = this.catalogMetadata.get(connectorId); if (catalogMetadata == null) { Catalog catalog = catalogsByConnectorId.get(connectorId); verify(catalog != null, "Unknown connectorId: %s", connectorId); ConnectorTransactionMetadata metadata = createConnectorTransactionMetadata(catalog.getConnectorId(), catalog); ConnectorTransactionMetadata informationSchema = createConnectorTransactionMetadata(catalog.getInformationSchemaId(), catalog); ConnectorTransactionMetadata systemTables = createConnectorTransactionMetadata(catalog.getSystemTablesId(), catalog); catalogMetadata = new CatalogMetadata( metadata.getConnectorId(), metadata.getConnectorMetadata(), metadata.getTransactionHandle(), informationSchema.getConnectorId(), informationSchema.getConnectorMetadata(), informationSchema.getTransactionHandle(), systemTables.getConnectorId(), systemTables.getConnectorMetadata(), systemTables.getTransactionHandle()); this.catalogMetadata.put(catalog.getConnectorId(), catalogMetadata); this.catalogMetadata.put(catalog.getInformationSchemaId(), catalogMetadata); this.catalogMetadata.put(catalog.getSystemTablesId(), catalogMetadata); } return catalogMetadata; }
public synchronized void checkConnectorWrite(ConnectorId connectorId) { checkOpenTransaction(); ConnectorTransactionMetadata transactionMetadata = connectorIdToMetadata.get(connectorId); checkArgument(transactionMetadata != null, "Cannot record write for connector not part of transaction"); if (readOnly) { throw new PrestoException(READ_ONLY_VIOLATION, "Cannot execute write in a read-only transaction"); } if (!writtenConnectorId.compareAndSet(null, connectorId) && !writtenConnectorId.get().equals(connectorId)) { throw new PrestoException(MULTI_CATALOG_WRITE_CONFLICT, "Multi-catalog writes not supported in a single transaction. Already wrote to catalog " + writtenConnectorId.get()); } if (transactionMetadata.isSingleStatementWritesOnly() && !autoCommitContext) { throw new PrestoException(AUTOCOMMIT_WRITE_CONFLICT, "Catalog " + connectorId + " only supports writes using autocommit"); } }
private void checkConnectorWrite(TransactionId transactionId, ConnectorId connectorId) { getTransactionMetadata(transactionId).checkConnectorWrite(connectorId); }
public synchronized ConnectorTransactionMetadata createConnectorTransactionMetadata(ConnectorId connectorId, Catalog catalog) { Connector connector = catalog.getConnector(connectorId); ConnectorTransactionMetadata transactionMetadata = new ConnectorTransactionMetadata(connectorId, connector, beginTransaction(connector)); checkState(connectorIdToMetadata.put(connectorId, transactionMetadata) == null); return transactionMetadata; }
@Override public void checkAndSetActive(TransactionId transactionId) { TransactionMetadata metadata = getTransactionMetadata(transactionId); metadata.checkOpenTransaction(); metadata.setActive(); }
@Override public TransactionInfo getTransactionInfo(TransactionId transactionId) { return getTransactionMetadata(transactionId).getTransactionInfo(); }
private synchronized Optional<ConnectorId> getConnectorId(String catalogName) { Optional<Catalog> catalog = catalogByName.get(catalogName); if (catalog == null) { catalog = catalogManager.getCatalog(catalogName); catalogByName.put(catalogName, catalog); if (catalog.isPresent()) { registerCatalog(catalog.get()); } } return catalog.map(Catalog::getConnectorId); }
public synchronized ListenableFuture<?> asyncAbort() { if (!completedSuccessfully.compareAndSet(null, false)) { if (completedSuccessfully.get()) { // Should not happen normally return immediateFailedFuture(new IllegalStateException("Current transaction already committed")); } // Already done return immediateFuture(null); } return abortInternal(); }