如何在mybatis-spring中使用@Transactional注释?

时间:2016-12-07 05:13:12

标签: java database spring mybatis

我尝试使用@Transactional中的spring注释和使用mybatis依赖项的mybatis-spring。这是服务层。

@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();
    }
}

如您所见,RuntimeException中抛出了insert1(),因此插入操作应该失败。但事实上,事实并非如此。记录已成功插入。为什么呢?

这是我的主要方法。

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配置。

<?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>

我在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>

1 个答案:

答案 0 :(得分:4)

正如@ M.Deinum提到的那样,我必须公开@Transactional公开的方法,换句话说,我必须改变

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

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

原因写在spring文档中。

  

方法可见性和@Transactional

     

使用代理时,您应该仅将@Transactional注释应用于具有公共可见性的方法。如果使用@Transactional注释对带保护的,私有的或包可见的方法进行注释,则不会引发错误,但带注释的方法不会显示已配置的事务设置。如果需要注释非公共方法,请考虑使用AspectJ(见下文)。