Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use @Transactional annotation in mybatis-spring?

I tried to use @Transactional annotation in spring and mybatis using mybatis-spring dependency. This is the service layer.

@Service
public class OracleService {

    @Autowired
    private TestMapper mapper;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Transactional(propagation = Propagation.REQUIRED,
                   rollbackFor = Exception.class,
                   value = "transactionManager")
    void insert1() {
        TestModel testModel = new TestModel(1, "title1", "content1");
        mapper.insert(testModel);
        throw new RuntimeException();
    }
}

As you can see, a RuntimeException is thrown out in insert1(), so the insert operation should fail. But in fact, it didn't. The record was inserted successfully. Why?

Here is my main method.

public class Launcher {
    public static void main(String[] args) {
        ApplicationContext cxt = new ClassPathXmlApplicationContext("spring-config.xml");
        OracleService oracleService = cxt.getBean(OracleService.class);
        try {
            oracleService.insert1();
        } catch(Exception e) {
            System.out.println("Exception occurred!");
        }
    }
}

Spring configuration.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"

       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">


    <context:component-scan base-package="com.database.learn"/>

    <bean id="oracleDataSource" class="oracle.jdbc.pool.OracleDataSource">
        <property name="URL" value="OracleJdbcUrl"/>
        <property name="user" value="user"/>
        <property name="password" value="password"/>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="oracleDataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="oracleDataSource" />
    </bean>

    <bean id="testMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.database.learn.TestMapper"/>
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager" />
</beans>

I used the following dependencies in pom.xml

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.1</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>11.2.0.3</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.3.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.2.RELEASE</version>
    </dependency>
like image 565
Searene Avatar asked Dec 07 '16 05:12

Searene


People also ask

What is the use of @transactional annotation in Spring?

The @Transactional annotation makes use of the attributes rollbackFor or rollbackForClassName to rollback the transactions, and the attributes noRollbackFor or noRollbackForClassName to avoid rollback on listed exceptions. The default rollback behavior in the declarative approach will rollback on runtime exceptions.

What is @transactional annotation in Spring MVC?

The @Transactional annotation is metadata that specifies that an interface, class, or method must have transactional semantics; for example, "start a brand new read-only transaction when this method is invoked, suspending any existing transaction".

What is the use of @transactional annotation in Java?

Transactional annotation provides the application the ability to declaratively control transaction boundaries on CDI managed beans, as well as classes defined as managed beans by the Java EE specification, at both the class and method level where method level annotations override those at the class level.

What is @transactional used for?

@Transactional annotation is used when you want the certain method/class(=all methods inside) to be executed in a transaction.


1 Answers

As @M.Deinum metioned, I have to make the method where @Transactional applied public, in other words, I have to change

@Transactional(propagation = Propagation.REQUIRED)
void insert1() {
    TestModel testModel = new TestModel(1, "title1", "content1");
    mapper.insert(testModel);
    throw new RuntimeException();
}

to

@Transactional(propagation = Propagation.REQUIRED)
public void insert1() {
    TestModel testModel = new TestModel(1, "title1", "content1");
    mapper.insert(testModel);
    throw new RuntimeException();
}

The reason is written in the spring documentation.

Method visibility and @Transactional

When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.

like image 65
Searene Avatar answered Oct 26 '22 07:10

Searene