How to use @Transactional annotation in mybatis-spring?

14,556

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.

Share:
14,556
Searene
Author by

Searene

A social nerd.

Updated on July 25, 2022

Comments

  • Searene
    Searene almost 2 years

    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>
    
  • Alex78191
    Alex78191 over 4 years
    Propagation REQUIRED is default
  • Alex78191
    Alex78191 over 4 years
    Why not to use AspectJ?
  • Alex78191
    Alex78191 over 4 years
    Why it's there is no warning for this?