【问题标题】:transactionTemplate doesn't work with mybatis but I don't know whytransactionTemplate 不适用于 mybatis 但我不知道为什么
【发布时间】:2016-06-13 06:17:03
【问题描述】:

我正在尝试使用 transactionTemplate 来管理我的交易。代码可能如下:

private Boolean isCleanSuccess(){
    return transactionTemplate.execute(new TransactionCallback<Boolean>() {
        @Override
        public Boolean doInTransaction(TransactionStatus transactionStatus) {
            String rmcName = "sync";
            StringBuilder sbSync = new StringBuilder();
            sbSync.append("delete from `t_sync_data_plan` WHERE 1=1");
            StringBuilder sbRmc = new StringBuilder();
            sbRmc.append("delete from `t_rmc_data` where `name`=\"")
                    .append(rmcName)
                    .append("\"");
            try{
                jdbcTemplate.execute(sbSync.toString());
                jdbcTemplate.execute(sbRmc.toString());
                /**
                  * throw the exception to make it rollback
                  */
                // throw new RuntimeException();
                return true;
            }catch (Exception ex){
                LOG.error(ex);
                transactionStatus.setRollbackOnly();
                return false;
            }
        }
    });
}

当我使用 jdbcTemplate 处理 Dao 时,它可以工作。但是,如果我在使用 myBatis 时抛出异常,它就无法回滚。 XML 代码列表如下:

<!-- rest transaction -->
<bean id="restTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="restDataSource"/>
</bean>

<bean id="restTransactionTemplate" name="restTransactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    <property name="transactionManager" ref="restTransactionManager"/>
</bean>

 <!--domain transacation-->
<bean id="domainTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="domainDataSource"/>
</bean>

<bean id="domainTransactionTemplate" name="domainTransactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    <property name="transactionManager">
        <ref bean="domainTransactionManager"/>
    </property>
</bean>

<!-- multi-datasource config -->
<bean id="multipleDataSource" class="com.angho.rest.db.MultipleDataSource" init-method="init">
    <property name="defaultTargetDataSource" ref="restDataSource"/>
    <property name="targetDataSources">
        <map>
            <entry key="restDataSource" value-ref="restDataSource"/>
            <entry key="domainDataSource" value-ref="domainDataSource"/>
        </map>
    </property>
    <property name="baseDaoDir" value="com.angho.rest"/>
    <property name="dataSourceNameMap">
        <map>
            <entry key="dao" value="restDataSource"/>
            <entry key="dao2" value="domainDataSource"/>
        </map>
    </property>
</bean>

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

不知道为什么回滚只在jdbcTemplate下有效,而在mybatis下就失效了。表引擎是 InnoDB。 你能帮我一下吗?这让我困惑了将近两个星期。 很抱歉我糟糕的英语给您带来了不便。

【问题讨论】:

    标签: java mysql spring mybatis spring-mybatis


    【解决方案1】:

    试试这样的:

    import org.apache.commons.dbcp2.BasicDataSource;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    

    ...

    @Value("${database.ip}")
    private String databaseIp;
    
    @Value("${database.user}")
    private String user;
    
    @Value("${database.password}")
    private String password;
    
    @Bean
    public DataSource getMybatisDataSource() throws URISyntaxException {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    
        dataSource.setUrl("jdbc:mysql://"+databaseIp+":3306/swords");
        dataSource.setUsername(user);
        dataSource.setPassword(password);
    
        return dataSource;
    }
    
    @Bean
    public DataSourceTransactionManager transactionManager() throws URISyntaxException {
        return new DataSourceTransactionManager(getMybatisDataSource());
    }
    
    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(getMybatisDataSource());
    
        return sessionFactory.getObject();
    }
    

    这样你就可以简单地使用@Transacional。

    更多信息: http://www.mybatis.org/spring/

    【讨论】:

    • 感谢您的回答。 'multipleDataSource'似乎有问题。我的同事刚刚找到原因并修复了这个错误。曾几何时,我也尝试使用@Transactional,但我的代码风格必须与其他人保持一致'。还是谢谢你!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-13
    • 2023-03-05
    • 1970-01-01
    • 2015-03-14
    相关资源
    最近更新 更多