Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are JDBI batch operation atomic?

Are JDBI batch operations (inserts or updates) atomic? Or do I need to wrap them in a transaction block?

like image 715
Jairam Avatar asked Sep 29 '22 20:09

Jairam


People also ask

Is JDBI an ORM?

Jdbi is not an ORM. There is no session cache, change tracking, "open session in view", or cajoling the library to understand your schema. Instead, Jdbi provides straightforward mapping between SQL and simple tabular data structures.

What is JDBI?

JDBI is a SQL convenience library for Java. It attempts to expose relational database access in idiomatic Java, using collections, beans, and so on, while maintaining the same level of detail as JDBC. It exposes two different style APIs, a fluent style and a sql object style.


2 Answers

According to java docs by default it's transactional. I don't know whether it fulfills the description of atomic but you don't need to wrap them in a transaction block. (FYI, there is @Transaction annotation you can use in case you want to do something transactional on DAO level, which is nicer than transaction blocks)

like image 149
Natan Avatar answered Oct 03 '22 00:10

Natan


My tests have shown that JDBI Batch operations are not atomic. In case we want all or nothing operation, we need to put the batch into a transaction.

I have created a simple test example. I used a MySQL database of InnoDB type.

package com.zetcode;

import org.skife.jdbi.v2.Batch;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.Handle;

public class JDBIEx6 {

    public static void main(String[] args) {

        DBI dbi = new DBI("jdbc:mysql://localhost:3306/testdb",
                "testuser", "test623");

        Handle handle = dbi.open();
        Batch batch = handle.createBatch();

        batch.add("DROP TABLE IF EXISTS Friends");
        batch.add("CREATE TABLE Friends(Id INT AUTO_INCREMENT PRIMARY KEY, Name TEXT)");
        batch.add("INSERT INTO Friends(Name) VALUES ('Monika')");
        batch.add("INSERT INTO Friends(Name) VALUES ('Tom')");
        batch.add("INSERT INTO Friends(Name) VALUES ('Jane')");
        batch.add("INSERT INTO Friends(Name) VALUES ('Robert')");

        batch.execute();
    }
}

If we deliberately modify one of the INSERT statements so that it fails, the table is created and all correct INSERT statements are saved.

The following is a Mavem POM file for the project.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zetcode</groupId>
    <artifactId>JDBIEx6</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.jdbi</groupId>
            <artifactId>jdbi</artifactId>
            <version>2.73</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>

    </dependencies>    
</project>

So I challange the fact that batch operations are atomic by default.

like image 45
Jan Bodnar Avatar answered Oct 03 '22 00:10

Jan Bodnar