Uploaded image for project: 'MariaDB ColumnStore'
  1. MariaDB ColumnStore
  2. MCOL-4549

[R2DBC-driver] Transaction is not persisted because commit is not called

    XMLWordPrintable

Details

    • Bug
    • Status: Closed (View Workflow)
    • Minor
    • Resolution: Fixed
    • None
    • Icebox
    • installation
    • 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.

      Attachments

        Activity

          People

            Unassigned Unassigned
            MatusMak Matúš Makatura
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.