В В спящем режиме когда я save()
объект в транзакции, и затем я откатываю его, сохраненный объект все еще остается в DB. Это странно, потому что этой проблемы не происходит с update()
или delete()
метод, только с save()
.
Вот код, который я использую:
DbEntity dbEntity = getDbEntity();
HibernateUtil.beginTransaction();
Session session = HibernateUtil.getCurrentSession();
session.save(dbEntity);
HibernateUtil.rollbackTransaction();
И вот класс HibernateUtil (просто включенные функции, я гарантирую getSessionFactory()
метод работает хорошо - существует обработчик Перехватчиков, но он не имеет значения теперь):
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();
}
}
Спасибо
Проверьте, поддерживает ли ваша база данных откат, т.е. с использованием таблиц InnoDB, а не MyISAM (вы можете смешивать транзакционные и нетранзакционные таблицы, но в большинстве случаев вы хотите, чтобы все ваши таблицы были InnoDB).
MySQL по умолчанию использует механизм хранения MyIsam. Поскольку MyISAM не поддерживает транзакции, операторы вставки, обновления и удаления напрямую записываются в базу данных. Операторы фиксации и отката игнорируются.
Чтобы использовать транзакцию, вам необходимо изменить механизм хранения ваших таблиц. Используйте эту команду:
ALTER TABLE имя_таблицы ENGINE = InnoDB;
(обратите внимание, что эти два механизма хранения различны, и вам нужно проверить свое приложение, если оно по-прежнему ведет себя так, как ожидалось)
{{ 1}}