perché i myBatis funzioni di inserimento / aggiornamento ora richiedono un commit dopo l'aggiunta di FK a DB?
Domanda
ho un progetto che utilizza myBatis per la persistenza. Metodo "A" al di sotto stava lavorando bene fino a quando ho aggiunto alcune chiavi esterne e convertito il mio tavolo da MyISAM a InnoDB. Dopo la conversione, il metodo "A" fallirebbe in silenzio, nemmeno un avvertimento nei registri. Dopo la conversione, unico metodo "B" fa un inserto di successo. Entrambi i metodi scrivere il corretto sql per i registri, ma solo "B" funziona.
Qualcuno mi può compilare sul motivo per cui ho bisogno di fare un commit ora, ma non c'era bisogno di fare un commit in precedenza?
//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;
}
Soluzione
MyISAM non è transazionale. Autocommit è attivo per impostazione predefinita (in realtà è ignorata dal driver JDBC in quanto ogni commit dichiarazione). InnoDB è transazionale e autocommit è anche disattivata per impostazione predefinita. Questo significa che si deve chiamare session.commit () o il DB non fa mai in realtà l'aggiornamento.
Vedere questa voce blog per ulteriori informazioni.
Si noti che si dovrebbe chiamare commettere piuttosto che lasciare le cose fino a autocommit. Lasciando autocommit off causerà problemi con il pool di connessioni poiché può lasciare istruzioni in uno stato indeterminato quando la connessione viene riutilizzata.