{"record":{"id":"f0b2d5be567a011f","repo":"prestodb/presto","slug":"autocommit-write-conflict","errorCode":"AUTOCOMMIT_WRITE_CONFLICT","errorMessage":"Catalog  only supports writes using autocommit","messagePattern":"Catalog  only supports writes using autocommit","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/transaction/InMemoryTransactionManager.java","lineNumber":597,"sourceCode":"\n        public synchronized void checkConnectorWrite(ConnectorId connectorId)\n        {\n            checkOpenTransaction();\n            ConnectorTransactionMetadata transactionMetadata = connectorIdToMetadata.get(connectorId);\n            checkArgument(transactionMetadata != null, \"Cannot record write for connector not part of transaction\");\n            if (readOnly) {\n                throw new PrestoException(READ_ONLY_VIOLATION, \"Cannot execute write in a read-only transaction\");\n            }\n            if (!writtenConnectorId.compareAndSet(null, connectorId) && !writtenConnectorId.get().equals(connectorId)) {\n                throw new PrestoException(\n                        MULTI_CATALOG_WRITE_CONFLICT,\n                        format(\n                                \"Multi-catalog writes not supported in a single transaction. Attempt write to catalog %s, but already wrote to catalog %s\",\n                                connectorId,\n                                writtenConnectorId.get()));\n            }\n            if (transactionMetadata.isSingleStatementWritesOnly() && !autoCommitContext) {\n                throw new PrestoException(AUTOCOMMIT_WRITE_CONFLICT, \"Catalog \" + connectorId + \" only supports writes using autocommit\");\n            }\n        }\n\n        public synchronized ListenableFuture<?> asyncCommit()\n        {\n            if (!completedSuccessfully.compareAndSet(null, true)) {\n                if (completedSuccessfully.get()) {\n                    // Already done\n                    return immediateFuture(null);\n                }\n                // Transaction already aborted\n                return immediateFailedFuture(new PrestoException(TRANSACTION_ALREADY_ABORTED, \"Current transaction has already been aborted\"));\n            }\n\n            ListenableFuture<?> functionNamespaceFuture = Futures.allAsList(functionNamespaceTransactions.values().stream()\n                    .map(transactionMetadata -> finishingExecutor.submit(transactionMetadata::commit))\n                    .collect(toImmutableList()));\n","sourceCodeStart":579,"sourceCodeEnd":615,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/transaction/InMemoryTransactionManager.java#L579-L615","documentation":"Thrown by TransactionMetadata.checkConnectorWrite when the connector's transaction metadata reports isSingleStatementWritesOnly() (a connector that only supports single-statement, autocommit writes) but the write occurs inside a non-autocommit context (an explicit multi-statement transaction).","triggerScenarios":"A write is performed against a catalog whose ConnectorMetadata isSingleStatementWritesOnly returns true while autoCommitContext is false, i.e. inside START TRANSACTION ... COMMIT rather than in autocommit mode.","commonSituations":"Wrapping writes to connectors like certain JDBC/Kafka-style catalogs (single-statement-write connectors) inside explicit transactions; application always wraps statements in transactions; connector upgraded to declare single-statement-writes-only and existing transactional code starts failing.","solutions":["Run the write in autocommit mode (do not wrap it in START TRANSACTION/COMMIT).","Remove only that connector's writes from the multi-statement transaction and execute them separately.","Switch to a connector that supports transactional writes if transactional semantics are required.","Check the connector's isSingleStatementWritesOnly capability before designing transactional workflows against it."],"exampleFix":"// before\nSTART TRANSACTION;\nINSERT INTO limited.t VALUES (1);\nCOMMIT;\n\n// after: autocommit\nINSERT INTO limited.t VALUES (1);","handlingStrategy":"validation","validationCode":"// Verify the connector supports transactional writes before using it in a transaction\nConnectorTransactionMetadata meta = transactionMetadata.getConnectorTransactionMetadata(connectorId);\nif (meta != null && meta.isSingleStatementWritesOnly()) {\n    // run this write in autocommit instead\n}","typeGuard":"boolean supportsTransactionalWrite(ConnectorMetadata metadata) {\n    return !metadata.isSingleStatementWritesOnly();\n}","tryCatchPattern":"try {\n    transactionMetadata.checkConnectorWrite(connectorId);\n} catch (PrestoException e) {\n    if (e.getErrorCode().getCode() == StandardErrorCode.AUTOCOMMIT_WRITE_CONFLICT.toErrorCode().getCode()) {\n        // move the statement outside the transaction and re-execute with autocommit\n    } else {\n        throw e;\n    }\n}","preventionTips":["Check the connector's isSingleStatementWritesOnly capability before wrapping its writes in transactions.","Do not blanket-wrap all statements in START TRANSACTION/COMMIT.","Execute single-statement-only connector writes in autocommit sessions.","Consult connector documentation for transactional write support."],"tags":["transaction","autocommit","presto","connector"],"backgroundTag":"autocommit-write-conflict","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}