0
votes

In my test case I have transactional method that creates user and then invokes async method in different thread that retrieves this user from database. In code below the user cannot be found in db and dao returns null. How to be sure that data will be there for different threads? It seems that flushing does not help. Do I need to manually commit? Setting isolation level to READ_UNCOMMITED also does not help.


    @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
What dB are you using?Lesiak
PostgreSQL. I've just tested on Oracle - same result.patryks

2 Answers

1
votes

Transaction is committed after whole transactional method is finished. Create user transaction can't be committed if it is in the main transaction. Changing previous code to something like this works.


    @Transactional
    public void createUser()  {

         User user = transactionalService.createUser();

         transactionalService.getUser(user.getId());

    }

And 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
votes

Make sure that your database supports READ_UNCOMMITTED isolation level (and, as a consequence, Dirty Reads)

Both databases you tested on (Postgres and Oracle) offer only higher isolation levels with less undesirable phenomena.

Postgres

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

The SQL standard defines one additional level, READ UNCOMMITTED. In PostgreSQL READ UNCOMMITTED is treated as READ COMMITTED.

Oracle

Does oracle allow the uncommitted read option?