Speedment поддерживает транзакции?

Я реализовал уровень персистентности, используя Speedment, и я хотел бы протестировать код с помощью модульных тестов с пружинной загрузкой. Я пометил свои юнит-тесты следующими аннотациями:

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class MovieServiceTest {
  ...
}

По умолчанию Spring запускает новую транзакцию, окружающую каждый метод тестирования и обратные вызовы @Before/@After, выполняя откат транзакции в конце. С Speedment, однако, это не похоже на работу.

Поддерживает ли Speedment транзакции через несколько вызовов, и если да, как мне настроить Spring для использования транзакций Speedment или как настроить Speedment для использования источника данных, предоставляемого Spring?

3 ответа

Решение

Поддержка транзакций была добавлена ​​в Speedment 3.0.17. Тем не менее, он не интегрируется с весной @Transactional-аннотации еще нет, поэтому вам нужно будет обернуть код, который вы хотите выполнить, в одну транзакцию, как показано здесь:

txHandler.createAndAccept(tx ->

    Account sender = accounts.stream()
        .filter(Account.ID.equal(1))
        .findAny()
        .get();

    Account receiver = accounts.stream()
        .filter(Account.ID.equal(2))
        .findAny()
        .get();

    accounts.update(sender.setBalance(sender.getBalance() - 100));
    accounts.update(receiver.setBalance(receiver.getBalance() + 100));

    tx.commit();
}

Вполне вероятно, что вы выполняете потоковую передачу по таблице, а затем выполняете операцию обновления / удаления, пока поток еще открыт. Большая часть базы данных не может справиться с открытым ResultSet на Connection а затем выполните операции обновления для того же соединения.

К счастью, есть простой способ: попробуйте собрать сущности, которые вы хотели бы изменить, в промежуточном Collection (такой как List или же Set), а затем использовать это Collection выполнить нужные операции.

Этот случай описан в Руководстве пользователя Speedment здесь

txHandler.createAndAccept(
    tx -> {
       // Collect to a list before performing actions
        List<Language> toDelete = languages.stream()
            .filter(Language.LANGUAGE_ID.notEqual((short) 1))
            .collect(toList());

        // Do the actual actions
        toDelete.forEach(languages.remover());

        tx.commit();
    }
);

AFAIK это не (пока) - исправление: кажется, настраивает одну транзакцию на поток / оператор.

Смотрите эту статью: https://dzone.com/articles/best-java-orm-frameworks-for-postgresql

Но это должно быть возможно реализовать с написанием специального расширения: https://github.com/speedment/speedment/wiki/Tutorial:-Writing-your-own-extensions

Редактировать:

По словам разработчика ускорения, один поток отображается на одну транзакцию: https://www.slideshare.net/Hazelcast/webinar-20150305-speedment-2

Другие вопросы по тегам