[MCOL-4549] [R2DBC-driver] Transaction is not persisted because commit is not called Created: 2021-02-20  Updated: 2022-06-08  Resolved: 2022-06-08

Status: Closed
Project: MariaDB ColumnStore
Component/s: installation
Affects Version/s: None
Fix Version/s: Icebox

Type: Bug Priority: Minor
Reporter: Matúš Makatura Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

The following text is copied over from GitHub issue #12.

When running update statements in transaction, changes are executed successfully but are not persisted as they are not committed.

Description of the problem

I'm studying r2dbc-client implementation to understand how clients are being built and I decided to test it against my local MariaDB databse of version 10.1.34 (later I managed to reproduce it on 10.4.13 hosted on AWS).

Statements executed in auto commit mode worked. However, when I run statement in transaction, it was executed successfully, but results were not persisted in database. When checking the table, I could see that while no new rows were inserted, AUTO_INCREMENT }}value was increased by {{1.

I tried downgrading driver to 0.8.4-rc, but the behavior was the same. However, when swapping driver with r2dbc-mysql, it worked as expected. My assumption therefore is that client and database are working as expected and it's the driver that is faulty.

It's worth noting that I used this driver in Spring WebFlux application and had no issues with Spring's annotation based transactions.

Investigation

I did a bit of debugging and it seems that org.mariadb.r2dbc.client.Context#serverStatus is not changed to correct one. Even after org.mariadb.r2dbc.client.ClientBase.LockAction#beginTransaction is called, status has value 2, which is flag for auto commit. So when org.mariadb.r2dbc.client.ClientBase.LockAction#commitTransaction is later called,[ condition for active transaction is evaluated as false|https://github.com/mariadb-corporation/mariadb-connector-r2dbc/blob/master/src/main/java/org/mariadb/r2dbc/client/ClientBase.java#L306] and therefore {{COMMIT} }query is never sent to the database.

I would not only expect server status to contain flag for 1 ( transaction), but also for flag 2 (auto commit) to be unset, as that would correspond to behavior described by R2DBC SPI.

Steps to reproduce

1. Create new application and ensure you have the following dependencies:

  • io.r2dbc:r2dbc-spi:0.8.3.RELEASE
  • org.mariadb:r2dbc-mariadb:1.0.0
  • dev.miku:r2dbc-mysql:0.8.2.RELEASE

2. Create database with the following table:

CREATE TABLE `users` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `first_name` varchar(255) COLLATE utf16_slovak_ci NOT NULL,
 `last_name` varchar(255) COLLATE utf16_slovak_ci NOT NULL,
 `email` varchar(255) COLLATE utf16_slovak_ci NOT NULL,
 PRIMARY KEY (`id`)
);

3. Execute this minimal Java code (replace database config or queries if necessary):

import dev.miku.r2dbc.mysql.MySqlConnectionConfiguration;
import dev.miku.r2dbc.mysql.MySqlConnectionFactory;
import io.r2dbc.client.R2dbc;
import org.mariadb.r2dbc.MariadbConnectionConfiguration;
import org.mariadb.r2dbc.MariadbConnectionFactory;
 
public class ClientTestJava {
 
    public static void main(String[] args) {
        R2dbc maria = getMariaDB();
        maria.useTransaction(handle -> handle.execute(
                "INSERT INTO `users` (`first_name`, `last_name`, `email`) VALUES ('MariaDB', 'Row', 'mariadb@test.com')"
        )).block();
 
        R2dbc mysql = getMySQL();
        mysql.useTransaction(handle -> handle.execute(
                "INSERT INTO `users` (`first_name`, `last_name`, `email`) VALUES ('MySQL', 'Row', 'mysql@test.com')"
        )).block();
    }
 
    private static R2dbc getMariaDB() {
        MariadbConnectionConfiguration config = MariadbConnectionConfiguration.builder()
                .host("localhost")
                .database("test")
                .username("root")
                .password("password")
                .build();
        return new R2dbc(new MariadbConnectionFactory(config));
    }
 
    private static R2dbc getMySQL() {
        MySqlConnectionConfiguration config = MySqlConnectionConfiguration.builder()
                .host("localhost")
                .database("test")
                .username("root")
                .password("password")
                .build();
        return new R2dbc(MySqlConnectionFactory.from(config));
    }
}

4. Check data in table and observe that only row inserted via MySQL driver is present.



 Comments   
Comment by Matúš Makatura [ 2021-02-20 ]

Hello, my bad for creating this in the incorrect project, but is not possible to submit directly under https://jira.mariadb.org/projects/R2DBC?

Comment by Roman [ 2022-06-08 ]

Could I ask you to recreate this issue and put it into the correct queue?

Generated at Thu Feb 08 02:51:11 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.