Можно ли проверить транзакционность процесса? - PullRequest
5 голосов
/ 26 октября 2010

Я хотел бы иметь возможность проверить, выполняется ли каждая единица работы в своей собственной транзакции или как часть одной глобальной транзакции.

У меня есть метод (определенный с помощью spring и hibernate),который имеет форму:

private void updateUser() {
    updateSomething();
    updateSomethingElse();
}

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

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void updateUserCreateNewTransaction() {
    updateUser();
}

@Transactional(propagation=Propagation.REQUIRED)
public void updateUserWithExistingTransaction() {
    updateUser();
}

updateUserCreateNewTransaction () вызывается из пакетного задания и updateUserWithExistingTransaction () из контекста веб-сервера.

Это работает.Однако очень важно, чтобы это поведение (пакета) не изменялось, поэтому я хочу создать тест, который проверяет это поведение.Если возможно, я бы хотел сделать это без изменения кода.

Так что некоторые из открытых мне вариантов:

  1. Подсчет транзакций, открытых в базе данных во времяВыполнение пакетного задания.

  2. Измените данные каким-то изощренным способом, чтобы по крайней мере одно обновление пользователя завершилось неудачно, в методе updateSomethingElse () и проверьте, что updateSomething () дляэтого пользователя не было.

  3. Проверка кода.

1 - это метод, зависящий от базы данных, и как я могу гарантировать, что hibernate победилв любом случае создать транзакцию?2 кажется лучше, но очень сложен в настройке.3 не очень практично, потому что нам нужно будет делать один для каждого выпуска.

Итак, есть ли у кого-нибудь метод, который позволил бы мне тестировать этот код, предпочтительно с помощью системного теста или интеграционного теста?

Ответы [ 2 ]

2 голосов
/ 26 октября 2010

Я бы попытался настроить тест в жгуте модульных тестов, используя HSQLDB в памяти и EasyMock (или какую-либо другую среду для насмешек) в памяти.

Тогда можно было бы действительно написать метод updateSomething() в HSQLбазы данных, но используйте фиктивный фреймворк, чтобы смоделировать метод updateSomethingElse() и выбросить RuntimeException из этого метода.Когда это будет сделано, вы можете выполнить запрос к HSQLDB, чтобы убедиться, что материал updateSomething() откатан.

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

0 голосов
/ 20 сентября 2011

Еще одна вещь, которую вы можете сделать, это настроить вывод журнала для транзакций Hibernate:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html#configuration-logging

Если вы сделаете категорию log4j для org.hibernate.transaction с leve журнала трассировки,расскажите все, что Hibernate делает для транзакций во время модульного теста.

...