Spring JPA @Transactional - данные не видны в разных потоках - PullRequest
0 голосов
/ 01 мая 2019

В моем тестовом примере у меня есть транзакционный метод, который создает пользователя, а затем вызывает асинхронный метод в другом потоке, который извлекает этого пользователя из базы данных. В приведенном ниже коде пользователь не может быть найден в БД, и dao возвращает ноль. Как быть уверенным, что данные будут там для разных потоков? Кажется, что промывка не помогает. Нужно ли фиксировать вручную? Установка уровня изоляции READ_UNCOMMITED также не помогает.


    @Transactional
    public void createUser()  {

        User user = new User();
        user.setLogin("test");

        userService.save(user);
        userService.flush();

        logger.debug("New user id {}", user.getId()); //id=1

        transactionalService.getUser(user.getId());

    }

TransactionalService


    @Async
    @Transactional
    public void getUser(Long id) {

        User user = userDao.getById(id);
        assertNotNull(user);
    } 

Ответы [ 2 ]

1 голос
/ 02 мая 2019

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


    @Transactional
    public void createUser()  {

         User user = transactionalService.createUser();

         transactionalService.getUser(user.getId());

    }

И TransactionalService


    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void createUser()  {

        User user = new User();
        user.setLogin("test");

        userService.save(user);
        logger.debug("New user id {}", user.getId()); //id=1

        return user

    }

    @Async
    @Transactional
    public void getUser(Long id) {

        User user = userDao.getById(id);
        assertNotNull(user);
    }


0 голосов
/ 02 мая 2019

Убедитесь, что ваша база данных поддерживает READ_UNCOMMITTED уровень изоляции (и, как следствие, Dirty Reads)

Обе базы данных, на которых вы тестировали (Postgres и Oracle), предлагают только более высокие уровни изоляции с меньшими нежелательными явлениями.

Postgres

https://www.postgresql.org/docs/9.3/sql-set-transaction.html

Стандарт SQL определяет один дополнительный уровень, ЧИТАТЬ НЕОБЕСПЕЧЕННЫЙ. В PostgreSQL READ UNCOMMITTED рассматривается как READ COMMITTED.

Oracle

Разрешает ли oracle параметр незафиксированного чтения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...