patryks
patryks

Reputation: 692

Spring JPA @Transactional - data not visible in different threads

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);
    } 

Upvotes: 1

Views: 1551

Answers (2)

patryks
patryks

Reputation: 692

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);
    }


Upvotes: 2

Lesiak
Lesiak

Reputation: 25986

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?

Upvotes: 0

Related Questions