Closed rinaldodev closed 1 month ago
@marcosgopen
Thanks @rinaldodev for your reproducer. As expected the db2 throws the exception 'ERROR: duplicate key value violates unique constraint "users_name_key"'. So the second prepare fails and the transaction is rolled back. And I can see that the rollback throws "XAException.XAER_RMERR" because the prepared transaction does not exist. I need to check if this is the expected behaviour. cc @graben
@rinaldodev: Could you please look at what happens if you use Agroal DataSource instead of the Narayana unpooled one.
@rinaldodev: Could you please look at what happens if you use Agroal DataSource instead of the Narayana unpooled one.
My original tests were with Agroal, that's when I saw it happening. I removed it from this reproducer just to reduce the scope. My original test is here: https://github.com/apache/camel-spring-boot-examples/pull/141
I can augment this one with Agroal if you believe it's necessary.
Hi @rinaldodev, I think you bumped into JBTM-3843. There is an upstream PR (on hold) to fix this issue and a PR to fix/discuss how pgjdbc handles rollback invocations when there has been a constraint violation during the prepare phase. We'll keep you posted
Hi @rinaldodev, I think you bumped into JBTM-3843. There is an upstream PR (on hold) to fix this issue and a PR to fix/discuss how pgjdbc handles rollback invocations when there has been a constraint violation during the prepare phase. We'll keep you posted
Thanks a lot. I'll follow this issue.
@rinaldodev: Could you please look at what happens if you use Agroal DataSource instead of the Narayana unpooled one.
My original tests were with Agroal, that's when I saw it happening. I removed it from this reproducer just to reduce the scope. My original test is here: https://github.com/apache/camel-spring-boot-examples/pull/141
I can augment this one with Agroal if you believe it's necessary.
I think it's not necessary at the moment. Let's wait for the Narayana patch to be committed.
@rinaldodev Narayana patch has been merged. You might be able to retest with a snapshot.
Thanks @graben! You were quicker than me sharing the news :-D
Thanks, I'll take a look.
@rinaldodev: Any news on this issue? Can it be closed regarding Narayana > 7.0.2?
@graben: I had a quick look, it seems that @rinaldodev's reproducer is now failing for something different than HEURISTIC_HAZARD
(log attached) so I suppose the latest snapshot from Narayana's main fixed the initial issue.
I'm getting a different error that seems related to the log implementation that arjuna is trying to use. I've rebased this example but the I get the same error.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'narayanaPropertiesInitializer' defined in class path resource [dev/snowdrop/boot/narayana/autoconfigure/NarayanaAutoConfiguration.class]: java.lang.reflect.InvocationTargetException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1806) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:313) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:313) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1443) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:904) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:782) ~[spring-beans-6.1.13.jar:6.1.13]
... 60 common frames omitted
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.arjuna.common.internal.util.propertyservice.BeanPopulator.getNamedInstance(BeanPopulator.java:75) ~[narayana-jta-7.0.3.Final-SNAPSHOT.jar:7.0.3.Final-SNAPSHOT (revision: 3acf8)]
at com.arjuna.common.internal.util.propertyservice.BeanPopulator.getDefaultInstance(BeanPopulator.java:38) ~[narayana-jta-7.0.3.Final-SNAPSHOT.jar:7.0.3.Final-SNAPSHOT (revision: 3acf8)]
at dev.snowdrop.boot.narayana.core.properties.NarayanaPropertiesInitializer.getPopulator(NarayanaPropertiesInitializer.java:151) ~[narayana-spring-boot-core-3.3.0-SNAPSHOT.jar:3.3.0-SNAPSHOT]
at dev.snowdrop.boot.narayana.core.properties.NarayanaPropertiesInitializer.setXARecoveryNodes(NarayanaPropertiesInitializer.java:95) ~[narayana-spring-boot-core-3.3.0-SNAPSHOT.jar:3.3.0-SNAPSHOT]
at dev.snowdrop.boot.narayana.core.properties.NarayanaPropertiesInitializer.afterPropertiesSet(NarayanaPropertiesInitializer.java:53) ~[narayana-spring-boot-core-3.3.0-SNAPSHOT.jar:3.3.0-SNAPSHOT]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853) ~[spring-beans-6.1.13.jar:6.1.13]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1802) ~[spring-beans-6.1.13.jar:6.1.13]
... 75 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[na:na]
at com.arjuna.common.internal.util.propertyservice.BeanPopulator.handleGroupProperty(BeanPopulator.java:273) ~[narayana-jta-7.0.3.Final-SNAPSHOT.jar:7.0.3.Final-SNAPSHOT (revision: 3acf8)]
at com.arjuna.common.internal.util.propertyservice.BeanPopulator.configureFromProperties(BeanPopulator.java:155) ~[narayana-jta-7.0.3.Final-SNAPSHOT.jar:7.0.3.Final-SNAPSHOT (revision: 3acf8)]
at com.arjuna.common.internal.util.propertyservice.BeanPopulator.getNamedInstance(BeanPopulator.java:72) ~[narayana-jta-7.0.3.Final-SNAPSHOT.jar:7.0.3.Final-SNAPSHOT (revision: 3acf8)]
... 81 common frames omitted
Caused by: java.lang.ExceptionInInitializerError: null
at com.arjuna.ats.jta.common.JTAEnvironmentBean.setXaRecoveryNodes(JTAEnvironmentBean.java:357) ~[narayana-jta-7.0.3.Final-SNAPSHOT.jar:7.0.3.Final-SNAPSHOT (revision: 3acf8)]
... 88 common frames omitted
Caused by: java.lang.IllegalArgumentException: Invalid logger interface com.arjuna.ats.jta.logging.jtaI18NLogger (implementation not found in jdk.internal.loader.ClassLoaders$AppClassLoader@2cdf8d8a)
at org.jboss.logging.Logger.doGetMessageLogger(Logger.java:2573) ~[jboss-logging-3.5.3.Final.jar:3.5.3.Final]
at org.jboss.logging.Logger.getMessageLogger(Logger.java:2532) ~[jboss-logging-3.5.3.Final.jar:3.5.3.Final]
at org.jboss.logging.Logger.getMessageLogger(Logger.java:2518) ~[jboss-logging-3.5.3.Final.jar:3.5.3.Final]
at com.arjuna.ats.jta.logging.jtaLogger.<clinit>(jtaLogger.java:16) ~[narayana-jta-7.0.3.Final-SNAPSHOT.jar:7.0.3.Final-SNAPSHOT (revision: 3acf8)]
... 89 common frames omitted
Following your steps to reproduce does not lead to an exception like this.
Following your steps to reproduce does not lead to an exception like this.
As suggested, I've built 7.0.3.Final-SNAPSHOT locally with ./build.sh -DskipTests
and replaced the version in the narayana.version
property.
After doing that, that's the error I'm getting. When using 7.0.2-Final, I get the original error.
If there are other changes that are needed to run with the SNAPSHOT version, please let me know.
If still compiling against NSB 3.2 you still might get Narayana 7.0.2. Add both Narayana dependencies from parent pom. That's what I did.
Hi @rinaldodev, I tried your reproducer again but I cannot reproduce the error you're getting. I'll list the steps I executed to clairfy what I did:
Thanks a lot, @jmfinelli. I believe this can be closed now.
I have set up a reproducer that uses 2 PostgreSQL databases enlisted in a XA transaction. It is a modified version of narayana-spring-boot-sample-2pc. One of the databases has a UNIQUE column while the other doesn't. The reproducer is available here: https://github.com/rinaldodev/narayana-spring-boot/tree/2ds-2pc-test.
I see a behavior that I'm not sure if it's expected:
PREPARE
is called for db1 (non-unique), works fine (TwoPhaseOutcome.PREPARE_OK
)PREPARE
is called for db2 (unique), db returns constraint violation as expected (TwoPhaseOutcome.PREPARE_NOTOK
)ROLLBACK PREPARED
is called for db1, works fines (TwoPhaseOutcome.FINISH_OK
)ROLLBACK PREPARED
is called for db2, but fails because the prepared transaction doesn't exist (TwoPhaseOutcome.HEURISTIC_HAZARD
)Is step 4 expected to occur?
Steps to run the example:
podman run --rm --name db1 -e POSTGRES_PASSWORD=password -p 5432:5432 docker.io/library/postgres:latest -c max_prepared_transactions=10
podman run --rm --name db2 -e POSTGRES_PASSWORD=password -p 5433:5432 docker.io/library/postgres:latest -c max_prepared_transactions=10
cd narayana-spring-boot-samples/narayana-spring-boot-sample-2pc
mvn spring-boot:run -Ddisable.checks > out.log
Trace logs are enabled so I suggest output to a file.
Here are some relevant parts from the log: