2

永続化のために myBatis を使用するプロジェクトがあります。以下の方法「A」は、いくつかの外部キーを追加し、テーブルを myISAM から innoDB に変換するまでは問題なく機能していました。変換後、メソッド "A" は警告なしでログに記録されずに失敗します。変換後、メソッド「B」のみが正常に挿入されます。どちらの方法でも正しい SQL がログに書き込まれますが、「B」のみが機能します。

今コミットする必要があるのに、以前はコミットする必要がなかった理由を誰か教えてもらえますか?

//doesnt work, but worked previously
public void A(Role role) {
    SqlSession session = sqlSessionFactory.openSession();
    try {
        RoleMapper mapper = session.getMapper(RoleMapper.class);
        mapper.updateByPrimaryKeySelective(role);
    }catch(Exception e){
        logger.error(e);
    } finally {
        session.close();
    }
    return;
}

//works correctly, but why?
public void B(Role role) {
    SqlSession session = sqlSessionFactory.openSession();
    try {
        RoleMapper mapper = session.getMapper(RoleMapper.class);
        mapper.updateByPrimaryKeySelective(role);
        session.commit();
    }catch(Exception e){
        logger.error(e);
    } finally {
        session.close();
    }
    return;
}
4

1 に答える 1

11

myISAM はトランザクション対応ではありません。自動コミットはデフォルトでオンになっています (実際には、すべてのステートメントがコミットされるため、JDBC ドライバーによって無視されます)。innoDB はトランザクション対応で、自動コミットもデフォルトでオフになっています。これは、session.commit() を呼び出す必要があることを意味します。そうしないと、DB が実際に更新を行うことはありません。

詳細については、このブログ エントリを参照してください。

自動コミットに任せるのではなく、commit を呼び出す必要があることに注意してください。自動コミットをオフのままにしておくと、接続が再利用されるときにステートメントが不明な状態のままになる可能性があるため、接続プールで問題が発生します。

于 2010-12-07T02:44:36.357 に答える