Stacksaga Mysql Reactive Support

Overview

stacksaga-mysql-reactive-support is the mysql reactive(non-blocking) implementation of the StackSaga Database Support modules. it provides all the necessary facilities for accessing the mysql database for the Stacksaga engine. and also it provides the endpoints for accessing the event-store to see the tracing details from the StackSaga Trace-Window.

Here you can see where the stacksaga-mysql-reactive-support fits into the overall Stacksaga architecture.

stacksaga components overview with mysql database support
Figure 1. Stacksaga components overview with mysql database support
read StackSaga Database Support modules to have a better understanding of the database support modules like the responsibilities, architecture etc.

Adding mysql support to your orchestrator application

adding mysql support to your orchestrator application consists of 3 simple steps.

Step-1

Add stacksaga-mysql-reactive-support as a dependency to your orchestrator application.

Step-2

Execute the shema creation script that is provided by the stacksaga-mysql-reactive-support module.

Step-3

Configure the mysql connection configurations.

The following sections will explain each step in detail.

Adding stacksaga-mysql-reactive-support as a dependency

Here is the way that you can add the library into your existing orchestrator application as a dependency.

Adding stacksaga-mysql-reactive-support as a dependency
<dependency>
    <groupId>org.stacksaga</groupId>
    <artifactId>stacksaga-mysql-reactive-support</artifactId>
    <version>${org.stacksaga.version}</version>
    <exclusions>
        <!--<exclusion>
            <groupId>org.stacksaga.cassandra</groupId>
            <artifactId>stacksaga-mysql-api-servlet</artifactId>
        </exclusion>-->
        <exclusion>
            <groupId>org.stacksaga</groupId>
            <artifactId>stacksaga-mysql-api-webflux</artifactId>
        </exclusion>
    </exclusions>
</dependency>
Make sure to exclude the stacksaga-mysql-api-servlet or stacksaga-mysql-api-webflux module based on your orchestrator application type (spring mvc or spring webflux). because, stacksaga-database-support modules provide built-in API for both spring mvc and spring webflux applications. for example if you are using spring mvc, then you should exclude the stacksaga-mysql-api-webflux module. or if you are using spring webflux, then you should exclude the stacksaga-mysql-api-servlet module. in this example we are excluding the stacksaga-mysql-api-webflux module because we are assuming that the orchestrator application is a spring mvc application.

Executing the schema creation script

Execute the following script in your mysql database to create the necessary tables and indexes that are required by the Stacksaga engine to save the transaction data.

Get the script from the following location on GitHub.

Make sure to verify that the script is the latest version.

Secondary Internal Service for Transaction Retry

Within the module that stacksaga-mysql-api-servlet or stacksaga-mysql-api-webflux, it provides a secondary HTTP port dedicated to internal communication for transaction retries. This port runs in the same application context as the main service but uses a separate connector, ensuring that retry requests from agent services are isolated from external traffic.

The endpoints on this secondary port are automatically created by the framework and are exclusively called by agent services to process retry transactions. This design ensures that internal retry operations do not interfere with the main application traffic.

The basic configurations can be changed as you prefer via the properties file. refer to the configuration properties table for more details.

Further customizations like changing the protocol (http/https), SSL configurations etc., developers can provide a customized WebServerFactoryCustomizer<?> through an implementation of WebServerFactoryCustomizerSupplier interface as a bean. it will override the default customizer that is provided by the framework.

Configuring mysql connection

By default stacksaga-mysql-reactive-support uses spring reactive R2DBC connection to connect to the mysql database. because even if your orchestrator application is a spring mvc application, the Stacksaga engine internally uses reactive programming model to achieve better performance and scalability. therefore if default R2DBC connection factory is not used in your application, you can configure the connection factory for the Stacksaga engine by providing the necessary properties in your application configuration file. or, otherwise, you can provide a custom io.r2dbc.spi.ConnectionFactory can provide it as a bean of org.stacksaga.mysql.reactive.provider.ConnectionFactoryProvider like below.

make sure to update the stacksaga.mysql.use-default-r2dbc-connection=false property in your application configuration file to mention not use the default r2dbc connection factory by the stacksaga.

@Configuration
public class CustomConfig {
    @Bean
    public ConnectionFactoryProvider customConnectionFactory() {
        ConnectionFactoryOptions options = ConnectionFactoryOptions.parse("r2dbc:mysql://localhost:3306/order-service-event-store")
                .mutate()
                .option(ConnectionFactoryOptions.USER, "dbuser")
                .option(ConnectionFactoryOptions.PASSWORD, "dbpassword")
                .build();
        ConnectionPoolConfiguration configuration = ConnectionPoolConfiguration.builder(ConnectionFactories.get(options))
                .initialSize(5)
                .maxSize(20)
                .maxIdleTime(java.time.Duration.ofMinutes(30))
                .build();
        return () -> new ConnectionPool(configuration);
    }
}

this approach keeps your default connection factory intact, and the Stacksaga engine will use the custom connection factory that you have provided.

Configuration Properties

Property Name Default Value Type Description

you can use the default spring r2dbc mysql connection properties that starts with spring.r2dbc prefix to configure the mysql connection for the stacksaga engine. otherwise, you can provide a custom one as mentioned here.

stacksaga.mysql.transaction.retry.crashed-restore-retention-period-seconds

300 (five-minutes)

long

if the transaction has not been updated after configured duration, it is considered as the transaction was dismissed due to crash, or it may be in a queue in rare case. even if the transaction is in a queue, the transaction is restored for retrying by considering it has crashed. the value should be provided in seconds.

stacksaga.mysql.transaction.retry.retention-period-seconds

60 (one-minute)

long

How long the transaction should be kept waiting to next expose the transaction for retrying. This ensures that avoiding the transaction retrying frequently withing a short period of time. the transaction is frozen for some period of time, even the transaction failed again after retrying recently.

stacksaga.retry.server.port

4455

int

The secondary HTTP port used for internal transaction retry communication.

stacksaga.retry.server.max-threads

20

int

Maximum number of threads for the retry service connector.

stacksaga.retry.server.min-spare-threads

4

int

Minimum number of spare threads for the retry service connector.

stacksaga.retry.server.address

0.0.0.0

string

The network address the retry service binds to.