Spring boot 11.567 TRACE 45788---[main]o.s.t.i.TransactionInterceptor:完成[org.springframework.data.jpa.repository.support.SimpleParepository.findFirstByUsername]的事务 2021-05-08 10:16:11.589 TRACE 45788---[main]o.s.t.i.TransactionInterceptor:无需为[org.springframework.data.jpa.repository.support.simplejpeparepository.toString]创建事务:此方法不是事务性的。 2021-05-08 10:16:11.597 TRACE 45788---[main]o.s.t.i.TransactionInterceptor:无需为[org.springframework.data.jpa.repository.support.simplejpeparepository.toString]创建事务:此方法不是事务性的。 2021-05-08 10:16:33.829信息45788---[main]c.p.p.t.r.service.impl.userserviceinpl:第二次读取的用户管理员密码是TohH 2021-05-08 10:16:33.859 TRACE 45788---[main]o.s.t.i.TransactionInterceptor:无需为[org.springframework.data.jpa.repository.support.simplejpeparepository.toString]创建事务:此方法不是事务性的。 2021-05-08 10:16:35.791 TRACE 45788---[main]o.s.t.i.TransactionInterceptor:在异常后完成[com.pohvii.playde.transaction.readuncommitted.service.impl.UserServiceImpl.readuncommitted]的事务:org.opentest4j.AssertionFailedError:应为:不相等,但为: 2021-05-08 10:16:35.791跟踪45788---[main]o.s.t.i.RuleBasedTransactionAttribute:应用规则确定事务是否应在org.opentest4j.AssertionFailedError上回滚错误:应为:不相等,但为: 2021-05-08 10:16:35.791跟踪45788---[main]o.s.t.i.RuleBasedTransactionAttribute:获胜回滚规则为空 2021-05-08 10:16:35.791跟踪45788---[main]o.s.t.i.RuleBasedTransactionAttribute:未找到相关回滚规则:应用默认规则 2021-05-08 10:16:35.878跟踪45788---[main].s.t.s.TransactionSynchronizationManager:清除事务同步 2021-05-08 10:16:35.878跟踪45788---[main].s.t.s.TransactionSynchronizationManager:删除的值[org.springframework.orm.jpa。EntityManagerHolder@21d9cd04]对于键[org.springframework.orm.jpa]。LocalContainerEntityManagerFactoryBean@260e3837]从线程[主] 2021-05-08 10:16:35.878跟踪45788---[main].s.TransactionSynchronizationManager:删除的值[org.springframework.jdbc.datasource。ConnectionHolder@7b5021d1]对于线程[main]中的键[HikariDataSource(NotebookHikariCP)]

Spring boot 11.567 TRACE 45788---[main]o.s.t.i.TransactionInterceptor:完成[org.springframework.data.jpa.repository.support.SimpleParepository.findFirstByUsername]的事务 2021-05-08 10:16:11.589 TRACE 45788---[main]o.s.t.i.TransactionInterceptor:无需为[org.springframework.data.jpa.repository.support.simplejpeparepository.toString]创建事务:此方法不是事务性的。 2021-05-08 10:16:11.597 TRACE 45788---[main]o.s.t.i.TransactionInterceptor:无需为[org.springframework.data.jpa.repository.support.simplejpeparepository.toString]创建事务:此方法不是事务性的。 2021-05-08 10:16:33.829信息45788---[main]c.p.p.t.r.service.impl.userserviceinpl:第二次读取的用户管理员密码是TohH 2021-05-08 10:16:33.859 TRACE 45788---[main]o.s.t.i.TransactionInterceptor:无需为[org.springframework.data.jpa.repository.support.simplejpeparepository.toString]创建事务:此方法不是事务性的。 2021-05-08 10:16:35.791 TRACE 45788---[main]o.s.t.i.TransactionInterceptor:在异常后完成[com.pohvii.playde.transaction.readuncommitted.service.impl.UserServiceImpl.readuncommitted]的事务:org.opentest4j.AssertionFailedError:应为:不相等,但为: 2021-05-08 10:16:35.791跟踪45788---[main]o.s.t.i.RuleBasedTransactionAttribute:应用规则确定事务是否应在org.opentest4j.AssertionFailedError上回滚错误:应为:不相等,但为: 2021-05-08 10:16:35.791跟踪45788---[main]o.s.t.i.RuleBasedTransactionAttribute:获胜回滚规则为空 2021-05-08 10:16:35.791跟踪45788---[main]o.s.t.i.RuleBasedTransactionAttribute:未找到相关回滚规则:应用默认规则 2021-05-08 10:16:35.878跟踪45788---[main].s.t.s.TransactionSynchronizationManager:清除事务同步 2021-05-08 10:16:35.878跟踪45788---[main].s.t.s.TransactionSynchronizationManager:删除的值[org.springframework.orm.jpa。EntityManagerHolder@21d9cd04]对于键[org.springframework.orm.jpa]。LocalContainerEntityManagerFactoryBean@260e3837]从线程[主] 2021-05-08 10:16:35.878跟踪45788---[main].s.TransactionSynchronizationManager:删除的值[org.springframework.jdbc.datasource。ConnectionHolder@7b5021d1]对于线程[main]中的键[HikariDataSource(NotebookHikariCP)],spring-boot,jpa,isolation-level,Spring Boot,Jpa,Isolation Level,将两个调用的结果分配给findFirstByUsername().get()以分离变量,并在调试时比较它们的引用ID。你会得到你的答案的 正确的测试包括在两次调用之间调用EntityManager.clear() public class UserServiceImpl implements UserService { private final UserRepository userRepository; @Override @Transactional(isola

将两个调用的结果分配给
findFirstByUsername().get()
以分离变量,并在调试时比较它们的引用ID。你会得到你的答案的

正确的测试包括在两次调用之间调用
EntityManager.clear()

public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;

    @Override
    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
    public void readUncommitted() {
        String firstReadPassword = userRepository.findFirstByUsername("admin").map(User::getPassword).get();
        log.info("first read user admin password is {}", firstReadPassword);
        // debug point below, and do update password
        String secondReadPassword = userRepository.findFirstByUsername("admin").map(User::getPassword).get();
        log.info("second read user admin password is {}", secondReadPassword);
        assertNotEquals(firstReadPassword, secondReadPassword);
    }
}

public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
    Optional<User> findFirstByUsername(String username);
}
@SpringBootTest
public class ReadUncommittedTest {
    @Configuration
    @ComponentScan("com.pohvii.playground.transaction.readuncommitted.service")
    @EntityScan("com.pohvii.playground.users.entity")
    @EnableJpaRepositories(basePackages = {"com.pohvii.playground.transaction.readuncommitted.repository"})
    @Import({
            DataSourceAutoConfiguration.class,
            HibernateJpaAutoConfiguration.class,
    })
    @EnableTransactionManagement
    static class TestConfiguration {
    }

    @Autowired
    private UserService userService;

    @Test
    void readUncommittedTest() throws Exception {
        userService.readUncommitted();
    }
}
2021-05-08 10:15:27.939 TRACE 45788 --- [           main] t.a.AnnotationTransactionAttributeSource : Adding transactional method 'com.pohvii.playground.transaction.readuncommitted.service.impl.UserServiceImpl.readUncommitted' with attribute: PROPAGATION_REQUIRED,ISOLATION_READ_UNCOMMITTED
2021-05-08 10:15:31.497 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Bound value [org.springframework.jdbc.datasource.ConnectionHolder@7b5021d1] for key [HikariDataSource (NotebookHikariCP)] to thread [main]
2021-05-08 10:15:31.498 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Bound value [org.springframework.orm.jpa.EntityManagerHolder@21d9cd04] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@260e3837] to thread [main]
2021-05-08 10:15:31.498 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Initializing transaction synchronization
2021-05-08 10:15:31.498 TRACE 45788 --- [           main] o.s.t.i.TransactionInterceptor           : Getting transaction for [com.pohvii.playground.transaction.readuncommitted.service.impl.UserServiceImpl.readUncommitted]
2021-05-08 10:15:32.681 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@21d9cd04] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@260e3837] bound to thread [main]
2021-05-08 10:15:32.681 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@7b5021d1] for key [HikariDataSource (NotebookHikariCP)] bound to thread [main]
2021-05-08 10:15:32.681 TRACE 45788 --- [           main] o.s.t.i.TransactionInterceptor           : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findFirstByUsername]
2021-05-08 10:15:32.686 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@21d9cd04] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@260e3837] bound to thread [main]
2021-05-08 10:15:32.769 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@21d9cd04] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@260e3837] bound to thread [main]
2021-05-08 10:15:32.777 DEBUG 45788 --- [           main] org.hibernate.SQL                        : select user0_.id as id1_0_, user0_.password as password2_0_, user0_.password_salt as password3_0_, user0_.role as role4_0_, user0_.username as username5_0_, user0_.version as version6_0_ from users user0_ where user0_.username=? limit ?
2021-05-08 10:15:32.914 TRACE 45788 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [VARCHAR] - [admin]
2021-05-08 10:15:32.977 TRACE 45788 --- [           main] o.s.t.i.TransactionInterceptor           : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findFirstByUsername]
2021-05-08 10:15:32.977  INFO 45788 --- [           main] c.p.p.t.r.service.impl.UserServiceImpl   : first read user admin password is TohH
2021-05-08 10:15:33.038 TRACE 45788 --- [           main] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.toString]: This method is not transactional.
2021-05-08 10:15:33.045 TRACE 45788 --- [           main] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.toString]: This method is not transactional.
2021-05-08 10:16:11.336 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@21d9cd04] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@260e3837] bound to thread [main]
2021-05-08 10:16:11.337 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@7b5021d1] for key [HikariDataSource (NotebookHikariCP)] bound to thread [main]
2021-05-08 10:16:11.337 TRACE 45788 --- [           main] o.s.t.i.TransactionInterceptor           : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findFirstByUsername]
2021-05-08 10:16:11.337 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@21d9cd04] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@260e3837] bound to thread [main]
2021-05-08 10:16:11.337 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@21d9cd04] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@260e3837] bound to thread [main]
2021-05-08 10:16:11.345 DEBUG 45788 --- [           main] org.hibernate.SQL                        : select user0_.id as id1_0_, user0_.password as password2_0_, user0_.password_salt as password3_0_, user0_.role as role4_0_, user0_.username as username5_0_, user0_.version as version6_0_ from users user0_ where user0_.username=? limit ?
2021-05-08 10:16:11.345 TRACE 45788 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [VARCHAR] - [admin]
2021-05-08 10:16:11.567 TRACE 45788 --- [           main] o.s.t.i.TransactionInterceptor           : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findFirstByUsername]
2021-05-08 10:16:11.589 TRACE 45788 --- [           main] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.toString]: This method is not transactional.
2021-05-08 10:16:11.597 TRACE 45788 --- [           main] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.toString]: This method is not transactional.
2021-05-08 10:16:33.829  INFO 45788 --- [           main] c.p.p.t.r.service.impl.UserServiceImpl   : second read user admin password is TohH
2021-05-08 10:16:33.859 TRACE 45788 --- [           main] o.s.t.i.TransactionInterceptor           : No need to create transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.toString]: This method is not transactional.
2021-05-08 10:16:35.791 TRACE 45788 --- [           main] o.s.t.i.TransactionInterceptor           : Completing transaction for [com.pohvii.playground.transaction.readuncommitted.service.impl.UserServiceImpl.readUncommitted] after exception: org.opentest4j.AssertionFailedError: expected: not equal but was: <TohH>
2021-05-08 10:16:35.791 TRACE 45788 --- [           main] o.s.t.i.RuleBasedTransactionAttribute    : Applying rules to determine whether transaction should rollback on org.opentest4j.AssertionFailedError: expected: not equal but was: <TohH>
2021-05-08 10:16:35.791 TRACE 45788 --- [           main] o.s.t.i.RuleBasedTransactionAttribute    : Winning rollback rule is: null
2021-05-08 10:16:35.791 TRACE 45788 --- [           main] o.s.t.i.RuleBasedTransactionAttribute    : No relevant rollback rule found: applying default rules
2021-05-08 10:16:35.878 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Clearing transaction synchronization
2021-05-08 10:16:35.878 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.orm.jpa.EntityManagerHolder@21d9cd04] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@260e3837] from thread [main]
2021-05-08 10:16:35.878 TRACE 45788 --- [           main] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.jdbc.datasource.ConnectionHolder@7b5021d1] for key [HikariDataSource (NotebookHikariCP)] from thread [main]