2016-05-13 15 views
0

Ich habe alle möglichen Beiträge zur Verwendung von Spring und MyBatis mit Transaktionen gesehen, aber ich habe ein Problem mit Rollbacks, die nicht mit normalem JDBC funktionieren.Rollback in MyBatis mit JDBC (kein Spring, keine Container)

Mein (Test/Wegwerf-) Code ist ziemlich einfach: Ich öffne eine Sitzung, füge eine Aufnahme ein, wirf einen Fehler ab und rolle die Transaktion zurück. Es ist jedoch immer verbindlich.

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

Die Protokolle zeigen:

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 [[email protected]] 
DEBUG | (JdbcTransaction.java:122) - Resetting autocommit to true on JDBC Connection [[email protected]] 
DEBUG | (JdbcTransaction.java:90) - Closing JDBC Connection [[email protected]] 
DEBUG | (PooledDataSource.java:344) - Returned connection 924748027 to pool. 

Hinweis das Zurücksetzen von autocommit bevor die Verbindung geschlossen .... Würde Zurücksetzen autcommit bevor die SqlSession verursachen meine zurückgerollten Transaktion begangen werden schließen? Wenn ja, ist das ein Fehler? Hat jemand JDBC mit Transaktionen arbeiten? Ich brauche es zum Testen, und ich würde etwas Hilfe wertschätzen. Momentan können keine Transaktionen zurückgesetzt werden.

Ich habe die MyBatis-Quelle angeschaut, und tatsächlich ruft sie resetAutocommit auf, bevor die Verbindung geschlossen wird. Ich benutze MySQL 5.6 und mysql-connector-java-5.1.36.jar für den Treiber, wenn jemand eine Lösung gefunden hat, die sie gefunden haben.

--- --- UPDATE

Mybatis-config.xml wird wie folgt:

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

Kannst du deinen 'mybatis-config.xml' Code posten? – Blank

+0

@Reno Ich habe den Beitrag aktualisiert. Danke, dass du dir das angeschaut hast. – user991945

Antwort

1

OK, ich die Antwort gefunden habe, von tiefer in mein Setup zu graben. Es scheint, dass die MySQL-Speicher-Engine, die ich für meine Test-DB installiert habe, ISAM ist. ISAM unterstützt keine Transaktionen. Ich wechselte zu InnoDB den folgenden SQL-tidbit verwenden und Transaktionen jetzt mit JDBC arbeiten:

ALTER TABLE bills ENGINE=InnoDB; 

Ich habe nicht versucht, aber es sieht aus wie Sie dies auch zu vorübergehend tun können:

SET default_storage_engine=InnoDB; 

Hoffentlich wird das jemandem helfen. Der Code/Config funktioniert wie oben beschrieben.