0

I'm working in Spring project, using mybatis 3 and oracle 11g.

I tried to rollback transactions when errors happen. However, rollback seems not to be working.

Source code bellow:

ApplicationContext.xml

    <tx:annotation-driven transaction-manager="transactionManager"/>
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

Service

int changeLimitSrcAcc(String src_acctno,String dest_acctno, String amt);

ServiceImpl

    @Override
    public int changeLimitSrcAcc(String src_acctno, String dest_acctno,
            String amt) {
        int result = 0;
        SqlSessionFactory sqlMapper = MyBatisService.getSessionFactory();
        SqlSession sqlSession = sqlMapper.openSession();
        CustomerAccountMapper mapper = sqlSession
                .getMapper(CustomerAccountMapper.class);

        try {
            int result1 = mapper.changeLimitSrcAcc(src_acctno, amt);
            int result2 = mapper.changeLimitDescAcc(dest_acctno, amt);
            if (result1 != 1 || result2 != 1)
                throw new Exception("Error happened");
            else result = 1;
            sqlSession.commit();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            sqlSession.rollback();
        } finally {
            sqlSession.close();
        }
        return result;
    }

I also tried to rollback a single transaction but it still committed.

I read on Mybatis home page and it said @transaction annotations doesn't need. I also put the annotations and nothing happened.

Any solutions?

Thanks.

Tran Tam
  • 699
  • 3
  • 14
  • 27
  • Personally, I would try the `@Transactional` annotation and let the method throw the exception instead of catching it. In this case you shouldn't need the `SqlSessionFactory` or the `SqlSession`, but can inject the mapper directly and Spring should take care of the rest. See the Spring documenation: http://docs.spring.io/autorepo/docs/spring/4.2.x/spring-framework-reference/html/transaction.html – Florian Schaetz Mar 10 '16 at 07:30
  • You are declaring a transaction manager outside Mybatis, so you can not use the SqlSession commit() or rollback(). Use instead the commit/rollback method asociated with the spring transaction manager as Florian Schaetz says. – jmad Mar 10 '16 at 08:36
  • Using @Transactional in the Service methods should defenitely work for you. Well, it worked for me fine. – Lucky Mar 19 '16 at 17:45

1 Answers1

1

You have 2 ways of managing transactions:

  1. Declarative Transaction Management (@Transactional annotation)
  2. Programmatic Transaction Management (manually do commit/rollback)

You try to do both. Decide - either let Spring manage transactions - configure myBatis with Spring config - more simple way or manually create DefaultTransactionDefinition etc.

Community
  • 1
  • 1
Sergii Shevchyk
  • 38,716
  • 12
  • 50
  • 61