I’m playing with technologies and framework for a new project: because I’m learning things probably useful for others, I’m gonna write here few notes about what I’ve learned. This is the fifth article of a series: the @Transactional annotation will be used.

Part 5 – Getting transactional

In this article, I will modify few classes of my project to show how to activate and use transactions.

In the previous articles, only select queries were used: they don’t need transaction; this time I want to “replace” (first delete and then insert) a series of record. Of course the following setup could be used for every set of change you have to perform on the database: normal update, single or bulk operations, complex combination of query that have to be performed atomically.

Technologies used:

  • Java 8
  • MyBatis 3.3
  • Spring 4.2
  • Mybatis-Spring 1.2.3
  • PostgreSQL JDBC 9.4

Step 1 – Dependency configuration

In the Maven’s pom.xml, I’ve added just one new dependency: org.springframework:spring-tx:${spring-framework.version}.

Step 2 – Implementing a transactional method

We are going to work on another table of the project’s database, tbit88_hp: the table structure is not important for the scope of this article, neither the MyBatis entities’ code is (Tbit88HpKey, Tbit88Hp, Tbit88HpMapper, Tbit88HpExample have been created by mybatis-generator).

The mybatis-generator configuration for this table is as follows:



<table schema="bita" tableName="tbit88_hp" enableSelectByPrimaryKey="true" enableSelectByExample="true" enableCountByExample="true" enableInsert="true" enableUpdateByPrimaryKey="true" enableUpdateByExample="true" enableDeleteByPrimaryKey="true" enableDeleteByExample="true" >
    <property name="immutable" value="false" />
    <property name="constructorBased" value="true" />
</table>


We create the DAO interface and implementation class, as we did before.


public interface Tbit88HpDao {

    public int replace(List<Tbit88Hp> records);

}

@Repository("tbit88HpDao")
public class Tbit88HpDaoImpl implements Tbit88HpDao {

    @Autowired
    private Tbit88HpMapper mapper;

    @Override
    @Transactional
    public int replace(List<Tbit88Hp> records) {
        for (Tbit88Hp record : records) {
            mapper.deleteByPrimaryKey(record);
        }
        for (Tbit88Hp record : records) {
            countmapper.insert(record);
        }
        return records.size;
    }
}

 

Step 3 – Spring configuration

For the activation of Spring’s transaction management, the project should have a configuration class similar to this example:

@Configuration
@Import({ MybatisSpringConfig.class })
@EnableTransactionManagement
public class DatabaseConf {

    @Bean
    public DataSource dataSource() {
        PGSimpleDataSource ds = new PGSimpleDataSource();
        // ...
        return ds;
    }

    @Bean
    public DataSourceTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}

The presence of the @EnableTransactionManagement annotation activates the transaction mechanism, otherwise the @Transactional annotations have no effect at all.

When the transactions are activated, you must define their manager: the sample classe uses a DataSourceTransactionManager.

Step 4 – Testing

 

Writing  a test class is a trivial task: just create the list of fake records and pass it to the replace method.

I’ve watched the application with log at debug level: this way I’ve tracked the queries with their parameters, the batching of the queries, and the use of the database connections/sessions by Spring.

Annunci