@Transactional Annotation + для вставки данных в цикл - PullRequest
4 голосов
/ 15 марта 2012

Я использую Spring 3, JPA + Hibernate для CMS приложения.В этом приложении у меня есть метод класса обслуживания, который аннотируется @Transactional Аннотация с помощью свойства rollBack.Внутри этого метода я вставляю данные (т.е. классы сущностей) в таблицу, используя цикл.Для каждого iteration классы сущностей цикла должны быть сохранены в базе данных.Но этого не происходит.Фиксация происходит только после завершения цикла и выхода из метода.Затем он фиксирует и сохраняет все сразу.Но мне нужно прочитать данные, как только они будут вставлены в базу данных перед фиксацией в этом случае.Я попытался с помощью ISOLATION LEVEL прочитать незафиксированное сообщение, но оно не поддерживалось, поскольку я использую JPADialect по умолчанию.Также пытался добавить hibernate реализацию jpaDialect, но все равно это не сработало.Пожалуйста, помогите обойти эту проблему.Еще одна вещь, есть ли способ использовать метод распространения требуется.

Ответы [ 3 ]

15 голосов
/ 15 марта 2012

Вы правы, это то, что I означает . Поскольку транзакции работают изолированно, другие транзакции не могут видеть их, прежде чем они будут зафиксированы. Но играть с уровнями изоляции - плохая практика. Я бы посоветовал вам запускать каждую итерацию в отдельной транзакции с началом и фиксацией внутри.

Это немного сложно в Spring, но вот пример:

public void batch() {
    for(...) {
        insert(...)
    }
}

//necessarily in a different class!
@Transactional
public void insert() {

}

Обратите внимание, что batch() - это , а не с комментариями @Transactional, а insert() должен принадлежать другому классу (служба Spring). Слишком долго комментировать, но это жизнь. Если вам это не нравится, вы можете использовать TransactionTemplate вручную.

5 голосов
/ 15 марта 2012

удалить транзакционную аннотацию для метода с циклом.

В цикле вызовите отдельный метод для выполнения сохранения, сделайте этот метод транзакционным

1 голос
/ 15 марта 2012

Вам нужно либо выполнить программные транзакции (классы Spring TransactionTemplate или PlatformTransactionManager, на которые нужно посмотреть, см. Spring Doc для программных транзакций , либо вы можете вызвать другой транзакционный метод изнутри вашего цикл, в котором транзакция помечена Propagation.REQUIRES_NEW, что означает, что каждый вызов этого метода выполняется в своей собственной транзакции, см. здесь . Я думаю, что второй подход требует определения метода REQUIRES_NEW в другом Spring bean-компонент из-за AOP-прокси. Вы также можете опустить REQUIRES_NEW, если цикл не выполняется внутри транзакции.

...