Getting Started with Doma-Transactions

Introduction

Here are some points about the transaction function that is indispensable for database access.

This article assumes Doma 2.44.0.

Please also read Introduction to Doma for an introduction to other features of Doma.

The first thing to consider

The first thing to consider regarding transactions. That is whether the framework you are using (such as Spring Framework) provides transactional functionality. If you do, please consider using it first.

When using Spring Framework

Spring Framework provides transactional functionality.

The getDataSource method of the implementation class of ʻorg.seasar.doma.jdbc.Config should be set to return the DataSource wrapped using ʻorg.springframework.jdbc.datasource.TransactionAwareDataSourceProxy. ** This is very important **.

After taking the above measures, refer to this guide and add @Transactional to the class or method of Spring component to execute transaction. available.

If you use doma-spring-boot, the above DataSource wrapping will be done automatically. Spring-boot-jpetstore is a sample application that uses the transaction function of Spring Framework using doma-spring-boot.

When using Quarkus

Quarkus provides transactional capabilities.

ʻThe getDataSource method of the implementation class of org.seasar.doma.jdbc.Configis theDataSource managed by Agroal which is the connection pool implementation of Quarkus. Please return `.

After taking the above measures, you can use transactions by adding @Transactional to the classes and methods of CDI components as described in this document.

If you use Quarkus Extension for Doma, the above DataSource setting will be done automatically. Quarkus-sample is a sample application that uses Quarkus' transaction function using Quarkus Extension for Doma.

When not using a framework that provides transactional functionality

Consider using Doma's local transactions.

The characteristics of Doma's local transactions are as follows.

Usage is described in the next section.

Doma's local transaction

The working code is in getting-started, but here's an excerpt of the important part.

Main.java


public class Main {

  public static void main(String[] args) {
    var config = createConfig();
    var tm = config.getTransactionManager();

    // setup database
    var appDao = new AppDaoImpl(config);
    tm.required(appDao::create);

    // read and update
    //④ Pass the lambda expression to the transaction manager method
    tm.required(
        () -> {
          var repository = new EmployeeRepository(config);
          var employee = repository.selectById(1);
          employee.age += 1;
          repository.update(employee);
        });
  }

  private static Config createConfig() {
    var dialect = new H2Dialect();
    //① Create a transaction-enabled data source
    var dataSource =
        new LocalTransactionDataSource("jdbc:h2:mem:tutorial;DB_CLOSE_DELAY=-1", "sa", null);
    var jdbcLogger = new Slf4jJdbcLogger();
    //② Create a transaction manager
    var transactionManager = new LocalTransactionManager(dataSource, jdbcLogger);
    //③ Make it possible to return the instance created in ① and ② above from the implementation class of Config.
    return new DbConfig(dialect, dataSource, jdbcLogger, transactionManager); 
  }
}

① Create a transaction-enabled data source

Instantiate LocalTransactionDataSource. In this example, the connection URL etc. is received by the constructor, but it also has a constructor that receives the DataSource instance.

② Create a transaction manager

Pass the instance of LocalTransactionDataSource created in ① above to the constructor to instantiate LocalTransactionManager.

③ Make it possible to return the instance created in ① and ② above from the implementation class of Config.

Pass the instance created in ① and ② to the constructor of DbConfig, which is the implementation class of Config, and instantiate it.

④ Pass the lambda expression to the transaction manager method

Tm here is an instance of LocalTransactionManager created in ②. You can execute a transaction by passing the process you want to handle in the transaction to the required method of tm as a lambda expression.

The required method is a method that starts if the transaction has not been started yet, and there are other methods such as the requiresNew method that always starts a new transaction and the notSupported method that temporarily stops the transaction. These methods can be nested and used.

The transaction is rolled back when you throw an exception from the lambda expression or call the setRollbackOnly method. Otherwise it will be committed.

One caveat is that if you have set up a local transaction, in principle all database access by Doma should be done via TransactionManager. Otherwise, you will get an exception.

in conclusion

I introduced the points of using transactions in Doma.

If you're using Doma and you think your transactions aren't working, you can refer to this article as well as the linked articles and samples.

Recommended Posts

Getting Started with Doma-Transactions
Getting Started with DBUnit
Getting Started with Ruby
Getting Started with Swift
Getting Started with Doma-Annotation Processing
Getting Started with Java Collection
Getting Started with JSP & Servlet
Getting Started with Java Basics
Getting Started with Spring Boot
Getting Started with Ruby Modules
Getting Started with Java_Chapter 5_Practice Exercises 5_4
[Google Cloud] Getting Started with Docker
Getting started with Java lambda expressions
Getting Started with Docker with VS Code
Getting Started with Ruby for Java Engineers
Getting Started with Docker for Mac (Installation)
Getting Started with Parameterization Testing in JUnit
Getting Started with Java Starting from 0 Part 1
Getting Started with Ratpack (4)-Routing & Static Content
Getting started with the JVM's GC mechanism
Getting Started with Language Server Protocol with LSP4J
Getting Started with Creating Resource Bundles with ListResoueceBundle
Getting Started with Java_Chapter 8_About Instances and Classes
Links & memos for getting started with Java (for myself)
Getting Started with Doma-Using Projection with the Criteira API
Getting Started with Doma-Using Subqueries with the Criteria API
Getting Started with Java 1 Putting together similar things
Getting started with Kotlin to send to Java developers
Getting Started with Doma-Using Joins with the Criteira API
Getting Started with Doma-Introduction to the Criteria API
Get started with Gradle
I tried Getting Started with Gradle on Heroku
Getting started with Java programs using Visual Studio Code
Getting Started with Legacy Java Engineers (Stream + Lambda Expression)
Get started with Spring boot
Get started with DynamoDB with docker
Completable Future Getting Started (First Future)
Proceed with Rust official documentation on Docker container (1. Getting started)
Getting started with Java and creating an AsciiDoc editor with JavaFX
Getting Started with Doma-Dynamicly construct WHERE clauses with the Criteria API
Getting Started with Reactive Streams and the JDK 9 Flow API
Getting Started with GitHub Container Registry instead of Docker Hub
Let's get started with parallel programming
Returning to the beginning, getting started with Java ② Control statements, loop statements
How to get started with slim
Summarize the main points of getting started with JPA learned with Hibernate
Getting started with Swift / C bridges with porting Echo Server using libuv
CompletableFuture Getting Started 2 (Try to make CompletableFuture)
Message cooperation started with Spring Boot
Getting Started with Micronaut 2.x ~ Native Build and Deploy to AWS Lambda ~
Getting Started with Machine Learning with Spark "Price Estimate" # 1 Loading Datasets with Apache Spark (Java)
I tried to get started with WebAssembly
[Deprecated] Getting started with JVM GC and memory management that I didn't understand
Part2 Part II. How to proceed with Getting Started Spring Boot Reference Guide Note ①