2010-12-15 101 views
1

J'utilise ibatis au printemps pour écrire sur mysql.printemps ibatis mysql problème asynchrone intermittent

J'ai un bug intermittent. À chaque cycle d'un processus, j'écris deux lignes à la base de données. Le prochain cycle que j'ai lu dans les rangées du cycle précédent. Parfois (une fois sur 30, parfois plus souvent, parfois moins), je ne récupère qu'une rangée de la db.

J'ai désactivé toutes les mises en cache auxquelles je peux penser. Mon sqlmap-config.xml dit simplement:

<sqlMapConfig> 
<settings enhancementEnabled="false" statementCachingEnabled="false" classInfoCacheEnabled="false"/> 

<sqlMap resource="ibatis/model/cognitura_core.xml"/> 

Y at-il un certain asynchronisme, ou la mise en cache d'autre au printemps ou ibatis ou le pilote mysql que je suis absent?

utilisant un ressort 3.0.5, 2.3.5 mybatis, mysql-connector-java 5.0.5

EDIT 1:

Serait-ce parce que je suis sur un pool de connexions (c3p0)? Est-il possible que l'insert soit toujours en cours de lecture? C'est bizarre, cependant, je pensais que tout se passerait de manière synchrone à moins que je ne déclare explicitement asynch?

Répondre

0

Appelez-vous SqlSession.commit() après les insertions? C3P0 "ferme" de manière asynchrone les connexions qui peuvent être appelées commit sous les couvertures. Cela pourrait expliquer le comportement que vous voyez.

+0

Merci pour la suggestion. Cela semble très prometteur .. Je ne suis pas sûr de ce que vous voulez dire par SqlSession.commit(). J'appelle l'insertion comme getSqlMapClientTemplate(). Insert ("insertIterationHistory", dataMap); - le modèle ne semble pas avoir de méthode de validation. Devrais-je simplement annoter la méthode avec @Transaction? Je suppose que je ne comprends pas vraiment où le commit est censé avoir lieu. Je pensais que chaque insertion serait auto-commit par défaut .. – bruce

+0

Hmmm .. Je viens de lire http://old.nabble.com/how-to-dusable-asynch-threads---td21196742.html en ajoutant du poids à votre explication asynchrone . Je pense que je vais juste utiliser un pool de connexion différent qui fait les choses de façon synchrone. – bruce

+0

Désolé, mal lu que MyBatis 3. Le principe est le même. Vous avez besoin d'une transaction pour obtenir une validation de base de données, donc l'ajout de l'annotation devrait fonctionner, en supposant que vous ayez un DataSourceTransactionManager configuré et que vous ayez quelque chose comme dans votre config Spring. – AngerClown

0

Je reçois un comportement similaire. C'est ce que je fais. J'ai une ancienne version d'IBATIS Je ne prévois pas de mise à niveau. Vous pouvez facilement déplacer cela dans un décorateur.

SqlMapSession session = client.openSession(); 
try { 
    try { 
     session.startTransaction(); 
     // do work 
     session.commitTransaction(); 
     // The transaction should be committed now, but it doesn't always happen. 
     session.getCurrentConnection().commit(); // Commit again :/ 
    } finally { 
     session.endTransaction(); 
    } 
} finally { 
    session.close(); // would be nice if it was 'AutoCloseable' 
}