Git Product home page Git Product logo

narayana-spring-boot's Introduction

Narayana Spring Boot

Narayana is a popular open source JTA transaction manager implementation supported by Red Hat. You can use the narayana-spring-boot-starter starter to add the appropriate Narayana dependencies to your project. Spring Boot automatically configures Narayana and post-processes your beans to ensure that startup and shutdown ordering is correct.

By default, Narayana transaction logs are written to a transaction-logs directory in your application home directory (the directory in which your application jar file resides). You can customize the location of this directory by setting a narayana.log-dir property in your application.properties file. Properties starting with narayana can also be used to customize the Narayana configuration. See the NarayanaProperties Javadoc for complete details.

Only a limited number of Narayana configuration options are exposed via application.properties. For a more more complex configuration you can provide a jbossts-properties.xml file. To get more details, please, consult Narayana project documentation.

To ensure that multiple transaction managers can safely coordinate the same resource managers, each Narayana instance must be configured with a unique ID. By default, this ID is set to 1. To ensure uniqueness in production, you should configure the narayana.transaction-manager-id property with a different value for each instance of your application.

Using databases

By default Narayana Transactional driver is used to enlist a relational database to a JTA transaction which provides a basic XAResource enlistment and recovery.

Add pooling

If you need a more sophisticated connection management, we advice you to use agroal-spring-boot-starter which provides connection pooling and many other features. To enable Agroal add the following dependency to your application configuration:

<dependency>
    <groupId>io.agroal</groupId>
    <artifactId>agroal-spring-boot-starter</artifactId>
    <version>2.x.x</version>
</dependency>

All Agroal configuration properties described in its documentation

Using messaging brokers

This Narayana starter supports two ways to enlist a messaging broker to a JTA transaction: plain connection factory and MessagingHub pooled connection factory.

By default Narayana Connection Proxy around the JMS connection factory is used which provides a basic XAResource enlistment and recovery.

Add pooling

If you need a more sophisticated connection management, you can enable MessagingHub support which provides connection pooling and many other features. To enable MessagingHub add the following property to you application configuration:

narayana.messaginghub.enabled=true

All MessagingHub configuration properties described in its documentation are mapped with a prefix narayana.messaginghub. So for example if you'd like to set an max connections pool size to 10, you could do that by adding this entry to your application configuration:

narayana.messaginghub.maxConnections=10

Release

Manually

Dry run:

mvn release:prepare -DdryRun

Tag:

mvn release:prepare

Deploy:

mvn release:perform

Set all modules to new SNAPSHOT version:

mvn versions:set
mvn versions:commit

narayana-spring-boot's People

Contributors

cmoulliard avatar cunningt avatar deepred-dev avatar geoand avatar graben avatar jacobdotcosta avatar luigidemasi avatar nicolaferraro avatar sgitario avatar sparty02 avatar zhfeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

narayana-spring-boot's Issues

spring-boot-1 vs. spring-boot-2 artifacts

I find quite confusing to have two separate starters for the two spring boot generations. The same artifact with two different version sounds a much better option to me.

Replace `jta`, `jdbc` and `jms` dependencies with `narayana-jta`

Instead of using separate modules of Narayana we could start using an aggregate one the same way as WildFly and EAP does.

The only issue is that narayana-jta contains a jbossts-properties.xml which our starter assumes to be absent by default. Before changing the dependencies we need to find a way to maintain backwards compatibility of Spring Boot and jbossts-properties.xml integration.

Add a workflow to remove old release tags

Release workflow is triggered with a new tag that starts with release-. After the release is done, this tag becomes useless. We could have another workflow with a cron to periodically delete them

Refactor pool properties handover between starter and core

Actually NarayanaProperties is directly handover between starter and core. This makes it difficult to easly create multiple datasources or connection factories with individual configurations. It should be considered to change core API to only transfer HashMap<String, String> for XADataSources and MessagingHubConnectionFactoryProperties for XAConnectionFactoryies.

Maybe a better layout could be developed to unify the usage of pools for jdbc/jms connections.

How to use JDBCStore instead of the default FileStore ?

I would like to use JDBCStore instead of the default FileStore for an application running on Kubernetes using PostgreSQL + JMS.
I wouldn't want to use StateFullSet but rather store the transaction log in the PostgreSQL database.

I have add this configuation in application.yml file
narayana: dbcp: enabled: true initialSize: 10 messaginghub: enabled: true maxConnections: 10

and add this jbossts-properties file:

com.arjuna.ats.internal.arjuna.objectstore.jdbc.JDBCStore com.arjuna.ats.internal.arjuna.objectstore.jdbc.accessors.DynamicDataSourceJDBCAccess;ClassName=org.postgresql.ds.PGSimpleDataSource;DatabaseName=sample-service;User=postgres;ServerName=jdbc-object-store;Password=admin Action true com.arjuna.ats.internal.arjuna.objectstore.jdbc.JDBCStore com.arjuna.ats.internal.arjuna.objectstore.jdbc.accessors.DynamicDataSourceJDBCAccess;ClassName=org.postgresql.ds.PGSimpleDataSource;DatabaseName=sample-service;User=postgres;ServerName=jdbc-object-store;Password=admin stateStore true com.arjuna.ats.internal.arjuna.objectstore.jdbc.JDBCStore com.arjuna.ats.internal.arjuna.objectstore.jdbc.accessors.DynamicDataSourceJDBCAccess;ClassName=org.postgresql.ds.PGSimpleDataSource;DatabaseName=sample-service;User=postgres;ServerName=jdbc-object-store;Password=admin Communication true

And this error occurred:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1717) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1312) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:886) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:790) ... 67 common frames omitted

I am wondering how to add this JDBCStore configuration ?

Support ordering of XAResource

The default order of XAResources in this basic sample (https://github.com/apinske/playground-mq/tree/narayana-spring-boot-issues-85) is: ActiveMQ first, H2 second. I think it is undefined what the actual order is. But it seems to be in registration order (MQ first by the listener).
This may lead to a race condition when processing the subsequent message. The MQ message is committed, while the DB TX is not yet committed (although will be, because prepare was successful). It's a small time window. But the Message may then already be consumed by another listener, which would then read old DB data.
Application Servers usually order MQ-Resources after DB-Resources, to mitigate exactly this sort of behaviour. I think JBoss does that too.
But standalone Narayana in Boot does not. Can we please have some sort of ordering when using Narayana in Boot?

Error enlisting after update to 3.1.0 in MariaDB and DB2

I have an application that use narayana-spring-boot with JPA and works fine with 3.0.0. After update it to 3.1.0 it begin to fail with MariaDB and DB2, although it runs with Postgres or H2.

I have been investigating the error and looks like the problem is on commit bbadc28.

My application has the following property:

narayana.transaction-manager-id=${random.uuid}

Then, like transaction-manager-id has more than 28 bytes, it's replaced with value generated with the new function shortenNodeIdentifier. But this cause that MariaDB and DB2 fail starting transaction (enlisting it). In case of MariaDB it throws a SQLSysntaxException.

Spring Boot 3.0 support

Is there Any road map about spring boot 3.0 support. Transaction packages are change javax to jakarta

Recovery Manager - Periodic Recovery Failed Connection Recurring issue.

Following the spring-boot-sample-2ds as a template, I have successfully enlisted two PostgreSQL databases to work with narayana.

In order to test the Recovery Manager, I interrupt a JDBC resource connection and observe the transaction log being written to the object storage. When I wait for the recovery manager to handle this error, I receive an error about establishing connection.

Out of this scenario, two questions come to mind:
1/ what is the proper way to enlist credentials to the Recovery Manager using this starter? I've tried using application.properties and calling RecoveryCredentialsProperties() in my configuration.

2/ Am I thinking about the recovery manager correctly in how it operates? Will it replay the transaction logs in object storage?

3/ If there are two resources in my transaction boundary (similar to spring-boot-sample-2ds) , should I be enlisting both of them to the recovery manager in the case of failure with one in particular?

I appreciate the time spent to answer these questions, it will help me a lot.

Cannot set isolationLevel with com.arjuna.ats.jdbc.isolationLevel with Spring Boot

The default isolation level with Narayana is:

private volatile int isolationLevel = Connection.TRANSACTION_SERIALIZABLE;

but this gives me the following error with stack trace because I am using Percona:

Caused by: java.sql.SQLException: Percona-XtraDB-Cluster doesn't recommend using SERIALIZABLE isolation with pxc_strict_mode = ENFORCING
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:545)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:513)
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:115)
	at com.mysql.cj.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:1983)
	at com.mysql.cj.jdbc.ConnectionImpl.setTransactionIsolation(ConnectionImpl.java:4023)
	at com.mysql.cj.jdbc.ConnectionWrapper.setTransactionIsolation(ConnectionWrapper.java:249)
	at com.arjuna.ats.internal.jdbc.drivers.modifiers.IsSameRMModifier.setIsolationLevel(IsSameRMModifier.java:77)
	at com.arjuna.ats.internal.jdbc.ConnectionImple.getConnection(ConnectionImple.java:826)
	at com.arjuna.ats.internal.jdbc.ConnectionImple.init(ConnectionImple.java:143)
	at com.arjuna.ats.internal.jdbc.ConnectionImple.<init>(ConnectionImple.java:111)
	at com.arjuna.ats.internal.jdbc.ConnectionManager.create(ConnectionManager.java:147)
	at me.snowdrop.boot.narayana.core.jdbc.NarayanaDataSource.getConnection(NarayanaDataSource.java:55)
	at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:158)
	at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:116)
	at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:79)
	... 33 common frames omitted

com.arjuna.ats.jdbc.isolationLevel property doesn't seem to take effect, nor setting System.setProperty("com.arjuna.ats.jdbc.isolationLevel", "1") does. It is always 8 (the default) in IsSameRMModifier. This is also in the logs before the exception:

o.h.e.j.e.i.JdbcEnvironmentInitiator     : HHH000342: Could not obtain connection to query metadata : Percona-XtraDB-Cluster doesn't recommend using SERIALIZABLE isolation with pxc_strict_mode = ENFORCING

How do I overcome this?

jbossts-properties.xml found first from narayana-jta-xxx.jar

In some circumstances jbossts-properties.xml is first found from narayana-jta-xxx.jar via class loader not from the starter. Since this one is not empty any property set is application.properties is ignored in NarayanaPropertiesInitializer.

A valid workaround seems to define empty jbossts-properties.xml in the project itself.

Support for Spring Boot 3

Hi,
looks current version of the lib is compatible with Spring Boot 2.X:

<spring-boot.version>2.7.2</spring-boot.version>

Would be good to support SpringBoot 3, which has been released recently.

SynchedLocalTransactionFailedException sending a message to a queue

I'm trying to send a message inside a transaction to a queue using a JmsTemplate which uses a XAConnectionFactory wrapped with XAConnectionFactoryWrapper#wrapConnectionFactory and pooling enabled, but I have an Exception:

org.springframework.jms.connection.SynchedLocalTransactionFailedException: Local JMS transaction failed to commit; nested exception is javax.jms.IllegalStateException: The session has already been closed

I have a demo project to reproduce this behavior here

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.