在我的测试案例中,我有一个事务方法,该方法创建用户,然后在另一个线程中调用异步方法,该线程从数据库中检索该用户。在下面的代码中,无法在db中找到用户,并且dao返回null。如何确保不同线程的数据在那里?似乎冲洗无济于事。我需要手动提交吗?将隔离级别设置为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); }
答案 0 :(得分:1)
整个事务方法完成后,事务便被提交。如果创建用户事务在主事务中,则无法提交。将先前的代码更改为类似的效果。
@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); }
答案 1 :(得分:0)
确保您的数据库支持READ_UNCOMMITTED
隔离级别(并因此导致脏读)
您测试过的两个数据库(Postgres和Oracle)仅提供较高的隔离级别,并减少了不良现象。
Postgres
https://www.postgresql.org/docs/9.3/sql-set-transaction.html
SQL标准定义了一个附加级别,即READ UNCOMMITTED。在PostgreSQL中,READ UNCOMMITTED被视为READ COMMITTED。
Oracle