使用JDBC在MyBatis中回滚(没有Spring,没有容器)

时间:2016-05-13 05:38:51

标签: mysql jdbc transactions mybatis rollback

我已经看过各种关于使用Spring和MyBatis进行事务处理的帖子,但是我遇到了回滚无法使用普通旧JDBC的问题。

我的(测试/一次性)代码非常简单:我打开会话,插入rec,故意抛出错误并回滚事务。但是,它总是提交。

public static void main (String[] args){
//-- omitted for brevity
        try {
            org.apache.ibatis.logging.LogFactory.useSlf4jLogging();
            inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            sess = sqlSessionFactory.openSession(false);

            BillsMapper mapper = sess.getMapper(BillsMapper.class);
            BillState billState = new BillState();
                billState.setBillId(-1);
                billState.setLastName("TESTER");
                billState.setFirstName("TESTER");
            mapper.insert(billState);
            logger.info("Post insert: key = {}", billState.getBillId());

            if(1 == 1)
                throw new RuntimeException("Error Thrown on purpose...testing rollback ");
            sess.commit();
        }catch(Exception e){
            logger.error("Error: {}", e);
            sess.rollback();
        }finally{
            sess.close();
            logger.info("Finito!");
        }
    }

日志显示:

DEBUG | (BaseJdbcLogger.java:145) - ==>  Preparing: insert into bills (users_userId, refId, firstName, ...
DEBUG | (BaseJdbcLogger.java:145) - ==> Parameters: 67(Integer), 67-120530180328(String), TESTER(String), ...
DEBUG | (BaseJdbcLogger.java:145) - <==    Updates: 1  
INFO  | (TestAction.java:50) - Post insert: key = 2478  
ERROR | (TestAction.java:56) - Error: {} java.lang.RuntimeException: Error Thrown on purpose...testing rollback at com.s2stest.TestAction.main(TestAction.java:53) 
DEBUG | (JdbcTransaction.java:79) - Rolling back JDBC Connection [com.mysql.jdbc.JDBC4Connection@371e88fb]  
DEBUG | (JdbcTransaction.java:122) - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@371e88fb]  
DEBUG | (JdbcTransaction.java:90) - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@371e88fb]  
DEBUG | (PooledDataSource.java:344) - Returned connection 924748027 to pool.

请注意在关闭连接之前重置autocommit ....在关闭SqlSession之前重置autcommit会导致我的回滚事务被提交吗?如果是这样,这是一个错误吗?有没有人让JDBC处理事务?我需要它进行测试,我非常重视一些帮助。现在,没有任何交易可以回滚。

我查看了MyBatis源代码,它在关闭连接之前确实调用了resetAutocommit。如果某人有他们找到的解决方法,我正在使用MySQL 5.6和mysql-connector-java-5.1.36.jar。

---更新---

mybatis-config.xml如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <settings>
        <setting name="logImpl" value="SLF4J" />
    </settings>
    <typeAliases>
        <package name="com.ship2storage.domain" />
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mytestDb?zeroDateTimeBehavior=convertToNull" />
                <property name="username" value="--shhh!!--" />
                <property name="password" value="--shhh!!--" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/ship2storage/db/maps/BillsMapper.xml" />  
    </mappers>

</configuration>

1 个答案:

答案 0 :(得分:1)

好的,我已经通过深入挖掘我的设置找到了答案。我为我的测试数据库安装的MySQL存储引擎似乎是ISAM。 ISAM 不支持支持交易。我使用以下SQL tidbit切换到InnoDB,并且事务现在可以使用JDBC:

ALTER TABLE bills ENGINE=InnoDB;

我没试过这个,但看起来你也可以暂时这样做:

SET default_storage_engine=InnoDB;

希望这会对某人有所帮助。上面发布的代码/配置有效。