Hibernate save() et l'annulation de la transaction
En veille prolongée lorsque je save()
un objet dans une transaction, et puis j'ai la restauration, l'a sauvé de l'objet reste dans la DB. C'est étrange parce que ce problème ne se produit pas avec le update()
ou delete()
méthode, juste avec save()
.
Voici le code que j'utilise:
DbEntity dbEntity = getDbEntity();
HibernateUtil.beginTransaction();
Session session = HibernateUtil.getCurrentSession();
session.save(dbEntity);
HibernateUtil.rollbackTransaction();
Et voici le HibernateUtil classe (juste les fonctions, je garantie la getSessionFactory()
méthode fonctionne bien, il est un Intercepteur de gestionnaire, mais il n'a pas d'importance maintenant):
private static final ThreadLocal<Session> threadSession = new ThreadLocal<Session>();
private static final ThreadLocal<Transaction> threadTransaction = new ThreadLocal<Transaction>();
/**
* Retrieves the current Session local to the thread.
* <p/>
* If no Session is open, opens a new Session for the running thread.
*
* @return Session
*/
public static Session getCurrentSession()
throws HibernateException {
Session s = (Session) threadSession.get();
try {
if (s == null) {
log.debug("Opening new Session for this thread.");
if (getInterceptor() != null) {
log.debug("Using interceptor: " + getInterceptor().getClass());
s = getSessionFactory().openSession(getInterceptor());
} else {
s = getSessionFactory().openSession();
}
threadSession.set(s);
}
} catch (HibernateException ex) {
throw new HibernateException(ex);
}
return s;
}
/**
* Start a new database transaction.
*/
public static void beginTransaction()
throws HibernateException {
Transaction tx = (Transaction) threadTransaction.get();
try {
if (tx == null) {
log.debug("Starting new database transaction in this thread.");
tx = getCurrentSession().beginTransaction();
threadTransaction.set(tx);
}
} catch (HibernateException ex) {
throw new HibernateException(ex);
}
}
/**
* Rollback the database transaction.
*/
public static void rollbackTransaction()
throws HibernateException {
Transaction tx = (Transaction) threadTransaction.get();
try {
threadTransaction.set(null);
if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() ) {
log.debug("Tyring to rollback database transaction of this thread.");
tx.rollback();
}
} catch (HibernateException ex) {
throw new HibernateException(ex);
} finally {
closeSession();
}
}
Grâce
est autocommit définie à false sur la connexion jdbc?
Oui, il est (<property name="hibernate.connexion.autocommit">false</propriété>). La couleur de la mode de la session est sur le mode de validation.
Oui, il est (<property name="hibernate.connexion.autocommit">false</propriété>). La couleur de la mode de la session est sur le mode de validation.
OriginalL'auteur Mark | 2010-04-09
Vous devez vous connecter pour publier un commentaire.
Vérifier si votre base de données prend en charge un roll back par exemple, si vous utilisez les tables InnoDB et pas MyISAM (vous pouvez mélanger des transactions et des non-transactionnelle de la table, mais dans la plupart des cas, vous souhaitez que toutes vos tables InnoDB).
Ok. Merci pour les commentaires. Je ne l'avais pas remarqué que vous utilisez MySQL, j'ai mis à jour ma réponse en conséquence.
merci man, maintenant il fonctionne comme prévu
OriginalL'auteur Pascal Thivent
MySQL utilise par défaut le moteur de stockage MyIsam. Comme le MyISAM ne supporte pas les transactions, insert, update et delete sont directement écrites dans la base de données. Le commit et rollback instructions sont ignorés.
Afin d'utiliser la transaction vous avez besoin de changer le moteur de stockage de tables vous. Utilisez cette commande:
ALTER TABLE table_name ENGINE = InnoDB;
(note comment jamais, que les deux moteurs de stockage sont différentes et vous avez besoin de tester votre application si il se comporte encore comme prévu)
OriginalL'auteur Kdeveloper