2010-04-09 2 views
9

В спящем режиме, когда i save() объект в транзакции, а затем я откат его, сохраненный объект все еще остается в БД. Это странно, потому что этот вопрос не происходит с методом update() или delete(), только с save().

Вот код, я использую:Спящий режим 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(); 
    } 
} 

Благодаря

+0

является автокоммит значение ЛОЖЬ на соединение jdbc? –

+0

Да, это ( false). Скрытый режим сеанса находится в режиме COMMIT. – Mark

ответ

8

Проверьте, если база данных поддерживает откат, т.е. если вы используете InnoDB таблицы и нет t MyISAM (вы можете смешивать транзакционные и не транзакционные таблицы, но в большинстве случаев вы хотите, чтобы все ваши таблицы были InnoDB).

+0

Я пробовал свой путь, но результат всегда тот же – Mark

+0

@Marcos Ok. Спасибо за ответ. Я не заметил, что вы используете MySQL, я обновил свой ответ соответственно. –

+0

спасибо, человек работает, как и ожидалось – Mark

5

MySQL по умолчанию использует механизм хранения MyIsam. Поскольку MyISAM не поддерживает транзакции, операторы вставки, обновления и удаления напрямую записываются в базу данных. Операторы commit и rollback игнорируются.

Для того, чтобы использовать транзакцию, вам необходимо изменить механизм хранения ваших таблиц. Используйте эту команду:

ALTER TABLE table_name ENGINE = InnoDB;

(обратите внимание, как всегда, что два двигателя хранения различны, и вам нужно протестировать приложение вы будете, если он по-прежнему ведет себя, как и ожидалось)

+4

Некоторое время двигатель MySQL по умолчанию является InnoDB. –

Смежные вопросы