{"record":{"id":"a9d132130fef9e54","repo":"apache/shardingsphere","slug":"25000-a9d132","errorCode":"25000","errorMessage":"Close transaction manager failed.","messagePattern":"Close transaction manager failed\\.","errorType":"exception","errorClass":"CloseTransactionManagerFailedException","httpStatus":null,"severity":"error","filePath":"kernel/transaction/type/xa/provider/narayana/src/main/java/org/apache/shardingsphere/transaction/xa/narayana/manager/NarayanaXATransactionManagerProvider.java","lineNumber":88,"sourceCode":"        if (null != xaRecoveryModule) {\n            xaRecoveryModule.removeXAResourceRecoveryHelper(new DataSourceXAResourceRecoveryHelper(xaDataSource));\n        }\n    }\n    \n    @SneakyThrows({SystemException.class, RollbackException.class})\n    @Override\n    public void enlistResource(final SingleXAResource singleXAResource) {\n        transactionManager.getTransaction().enlistResource(singleXAResource.getDelegate());\n    }\n    \n    @Override\n    public void close() {\n        try {\n            recoveryManagerService.stop();\n            // CHECKSTYLE:OFF\n        } catch (final Exception ex) {\n            // CHECKSTYLE:ON\n            throw new CloseTransactionManagerFailedException(ex);\n        }\n        recoveryManagerService.destroy();\n        cleanPropertiesFactory();\n        cleanBeanInstances();\n        cleanAtomicActionRecovery();\n        cleanXARecoveryModule();\n        cleanStoreManager();\n    }\n    \n    private void cleanPropertiesFactory() {\n        ReflectionUtils.setStaticFieldValue(PropertiesFactory.class, \"delegatePropertiesFactory\", null);\n    }\n    \n    private void cleanBeanInstances() {\n        ReflectionUtils.<ConcurrentMap<String, Object>>getStaticFieldValue(BeanPopulator.class, \"beanInstances\").clear();\n    }\n    \n    private void cleanAtomicActionRecovery() {","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/kernel/transaction/type/xa/provider/narayana/src/main/java/org/apache/shardingsphere/transaction/xa/narayana/manager/NarayanaXATransactionManagerProvider.java#L70-L106","documentation":"NarayanaXATransactionManagerProvider.close() stops the Narayana recovery manager and performs aggressive static-state cleanup (PropertiesFactory, bean instances, atomic action recovery, XA recovery module, store manager). If recoveryManagerService.stop() throws any Exception, it is wrapped in CloseTransactionManagerFailedException (SQLSTATE class 25000) and the remaining cleanup steps are skipped.","triggerScenarios":"Shutting down or re-initializing the proxy (or a unit test repeatedly creating/destroying Narayana XA transaction managers) when the Narayana recovery manager cannot stop cleanly — e.g. recovery store corruption, an already-stopped service, or static Narayana state left dirty by a previous close that failed midway.","commonSituations":"Repeated redeployments in the same JVM without full static cleanup; Narayana object-store directory (default under the working dir) locked or corrupted; version mismatch between narayana artifacts on the classpath; tests that instantiate the provider multiple times against the same static PropertiesFactory.","solutions":["Inspect the cause inside CloseTransactionManagerFailedException — the original Narayana exception names the real failure.","Clean or delete the Narayana object store directory and any stale recovery locks, then restart.","Ensure only one Narayana XA manager lifecycle per JVM: avoid creating a second instance before the first fully closed; restart the JVM between reconfigurations.","Align Narayana artifact versions on the classpath (no mixed jta/narayana versions).","If closing during shutdown is failing, verify the recovery store path is writable and not shared with another running instance."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { provider.close(); } catch (final CloseTransactionManagerFailedException ex) { Exception cause = (Exception) ex.getCause(); log.warn(\"Narayana close failed: {}\", cause.getMessage()); /* clean object store and restart JVM if state is dirty */ }","preventionTips":["Log and inspect the wrapped Narayana cause before retrying shutdown.","Avoid repeated create/close cycles of the XA manager in one JVM (tests included).","Keep the Narayana object store writable and unshared between instances.","Pin one consistent Narayana version across the classpath."],"tags":["xa","narayana","shutdown","transaction-manager","recovery"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}