2016-12-07 3 views
2

J'ai essayé d'utiliser l'annotation @Transactional dans spring et mybatis en utilisant la dépendance mybatis-spring. C'est la couche de service.Comment utiliser l'annotation @Transactional dans 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(); 
    } 
} 

Comme vous pouvez le voir, un RuntimeException est jeté dans insert1(), l'opération d'insertion devrait échouer. Mais en fait, ce n'est pas le cas. L'enregistrement a été inséré avec succès. Pourquoi?

Voici ma méthode principale.

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!"); 
     } 
    } 
} 

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

J'ai utilisé les dépendances suivantes 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> 
+0

Avez-vous ajouté @EnableTransactionManagement –

+0

@ShubhamAgarwal Merci pour le rappel, je l'ai juste ajouté dans la configuration du ressort, mais cela n'a toujours pas fonctionné. – Searene

+0

Et avez-vous enveloppé votre source de données sous transactionManager? Manière d'annotation: [link] (http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/annotation/EnableTransactionManagement.html) Manière XML: [link] (http: // docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction.html#transaction-strategies) –

Répondre

1

Comme @ M.Deinum metioned, je dois faire de la méthode où @Transactional appliquée publique, autrement dit, je dois changer

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

La raison est écrite dans la documentation du printemps.

Méthode visibilité et @Transactional

Lors de l'utilisation des procurations, vous devez appliquer l'annotation @Transactional uniquement aux méthodes avec une visibilité publique. Si vous annotez des méthodes protected, private ou package-visible avec l'annotation @Transactional, aucune erreur n'est générée, mais la méthode annotée ne présente pas les paramètres transactionnels configurés. Considérez l'utilisation d'AspectJ (voir ci-dessous) si vous avez besoin d'annoter des méthodes non publiques.