Moh*_*eem 5 hibernate spring-transactions spring-boot
从Spring Framework 5.2 版开始,每当一个方法被标记为 @Transactional(readOnly=true) 我应该期待:
但是,当我尝试使用 readOnly=true 时,上述两个条件都不符合预期。
@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig {
@Bean
@Primary
DataSource dataSource() throws PropertyVetoException {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/db_example");
config.setDriverClassName(Driver.class.getName());
config.setConnectionTestQuery("SELECT 1");
config.setUsername("root");
config.setPassword("root1234");
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
config.addDataSourceProperty("useServerPrepStmts", "true");
config.setMaximumPoolSize(11);
return new HikariDataSource(config);
}
@Bean
@Primary
public EntityManagerFactory entityManagerFactory() throws PropertyVetoException {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect");
vendorAdapter.setShowSql(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan("com.example.hibernatedemo");
factory.setDataSource(dataSource());
Properties properties = new Properties();
properties.setProperty("hibernate.generate_statistics", "true");
factory.setJpaProperties(properties);
factory.afterPropertiesSet();
return factory.getObject();
}
@Bean
PlatformTransactionManager transactionManager() throws PropertyVetoException {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory());
txManager.setDataSource(dataSource());
return txManager;
}
}
@Service
public class PostService {
.
.
.
@Transactional(readOnly = true)
public List<Post> getByTitles(List<String> titles) {
List<Post> posts = postDao.getByTitle(titles);
System.out.println(entityManager.getFlushMode());
Session session = (Session) entityManager.getDelegate();
System.out.println(session.isDefaultReadOnly());
printLoadedState(posts);
return posts;
}
}
@Repository
public class PostDao {
.
.
.
public List<Post> getByTitle(List<String> titles) {
Session session = (Session) entityManager.getDelegate();
return session.createQuery("select p from Post p where title IN :titles", Post.class)
.setParameter("titles", titles).getResultList();
}
}
Run Code Online (Sandbox Code Playgroud)
以下是日志:
[2019-11-25 18:37:30] [http-nio-8091-exec-2] DEBUG o.s.orm.jpa.JpaTransactionManager.getTransaction - [ ] Creating new transaction with name [com.example.hibernatedemo.service.PostService.getByTitles]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
[2019-11-25 18:37:30] [http-nio-8091-exec-2] DEBUG o.s.jdbc.datasource.DataSourceUtils.prepareConnectionForTransaction - [ ] Setting JDBC Connection [HikariProxyConnection@676721780 wrapping com.mysql.cj.jdbc.ConnectionImpl@66522ead] read-only
[2019-11-25 18:37:30] [http-nio-8091-exec-2] DEBUG o.h.e.t.internal.TransactionImpl.<init> - [ ] On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false
[2019-11-25 18:37:30] [http-nio-8091-exec-2] DEBUG o.h.e.t.internal.TransactionImpl.begin - [ ] begin
.
.
.
flushMode: COMMIT
readOnly: false
.
.
.
[2019-11-25 18:37:33] [http-nio-8091-exec-2] DEBUG o.s.orm.jpa.JpaTransactionManager.processCommit - [ ] Initiating transaction commit
[2019-11-25 18:37:33] [http-nio-8091-exec-2] DEBUG o.s.orm.jpa.JpaTransactionManager.doCommit - [ ] Committing JPA transaction on EntityManager [SessionImpl(1945987926<open>)]
[2019-11-25 18:37:33] [http-nio-8091-exec-2] DEBUG o.h.e.t.internal.TransactionImpl.commit - [ ] committing
[2019-11-25 18:37:33] [http-nio-8091-exec-2] DEBUG o.s.jdbc.datasource.DataSourceUtils.resetConnectionAfterTransaction - [ ] Resetting read-only flag of JDBC Connection [HikariProxyConnection@676721780 wrapping com.mysql.cj.jdbc.ConnectionImpl@66522ead]
Run Code Online (Sandbox Code Playgroud)
pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)
如果需要更多信息,请添加评论。我可能错过了基本配置或其他东西。任何帮助表示赞赏。
Ken*_*han -1
好吧,我再看一遍源代码。HibernateJpaDialect
如果显式设置为JpaTransactionManager
(您已经通过设置HibernateJpaVendorAdapter
为LocalContainerEntityManagerFactoryBean
)并且在 5.1 RC1 发布的此修复之后,它应该可以工作。
您测试的方法是否有可能被某些 bean 的@Transactional
另一个方法调用@Transactional
,而外部@Transactional
方法是read-only=false
?因为外部方法的设置@Transactional
只会覆盖内部方法。(假设内层不设为PROPAGATION_REQUIRES_NEW
)。
另一方面,你也可以尝试改变@Transactional
你测试的方法,PROPAGATION_REQUIRES_NEW
看看是否readOnly = true
可以生效。
归档时间: |
|
查看次数: |
1207 次 |
最近记录: |