我已经看过各种关于使用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>
答案 0 :(得分:1)
好的,我已经通过深入挖掘我的设置找到了答案。我为我的测试数据库安装的MySQL存储引擎似乎是ISAM。 ISAM 不支持支持交易。我使用以下SQL tidbit切换到InnoDB,并且事务现在可以使用JDBC:
ALTER TABLE bills ENGINE=InnoDB;
我没试过这个,但看起来你也可以暂时这样做:
SET default_storage_engine=InnoDB;
希望这会对某人有所帮助。上面发布的代码/配置有效。