@Transactional 即使使用编译时编织插件也会抛出 TransactionRequiredException 与 ASPECTJ ?
@Transactional
抛出 TransactionRequiredException
:没有可用于当前线程的实际事务的 EntityManager
- 无法可靠地处理持久性 使用 AspectJ 时,即使安装了编译时编织插件并安装了所有 AspectJ 依赖项和开发工具。
可能类似的问题: 为什么要从 AspectJ 切换到代理模式导致“TransactionRequiredException:执行更新/删除查询”不再发生?
我打算使用AspectJ而不是Spring AOP提高我的应用程序的性能。
这里我展示了三个文件的一部分。 AspectJ 开发工具包已安装。
pom.xml:
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.8</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.8</version>
</dependency>
<dependency>
<groupId>dev.aspectj</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.13.1</version>
<type>maven-plugin</type>
</dependency>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<!-- <goal>test-compile</goal> -->
</goals>
</execution>
</executions>
<configuration>
<complianceLevel>17</complianceLevel>
<forceAjcCompile>true</forceAjcCompile>
<weaveDirectories>
<weaveDirectory>${project.build.outputDirectory}</weaveDirectory>
</weaveDirectories>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
</plugin>
</plugins>
</build>
XService.java:
@Service
@Transactional(propagation = Propagation.SUPPORTS)
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class BridgeService {
...
@Transactional
private void persistAvatarResource(String resCode, String start) {
AvatarRes avatarRes = new AvatarRes();
avatarRes.setClient(client);
avatarRes.setAvatar(avatar);
avatarRes.setRes(getResource(resCode));
avatarRes.setStart(PHPHelper.toInt(start));
entityManager.persist(avatarRes);
}
...
}
DatabaseConfig.java:
@Configuration
@EnableJpaRepositories("com.lixar.apba.repository")
@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
public class DatabaseConfiguration {
private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);
@Inject
private Environment env;
@Autowired(required = false)
private MetricRegistry metricRegistry;
@Bean(destroyMethod = "close")
@ConditionalOnExpression("!environment.acceptsProfiles('cloud') && !environment.acceptsProfiles('heroku')")
public DataSource dataSource(DataSourceProperties dataSourceProperties, JHipsterProperties jHipsterProperties, CacheManager cacheManager) {
log.debug("Configuring Datasource");
if (dataSourceProperties.getUrl() == null) {
log.error("Your database connection pool configuration is incorrect! The application" +
" cannot start. Please check your Spring profile, current profiles are: {}",
Arrays.toString(env.getActiveProfiles()));
throw new ApplicationContextException("Database connection pool is not configured correctly");
}
HikariConfig config = new HikariConfig();
config.setDataSourceClassName(dataSourceProperties.getDriverClassName());
config.addDataSourceProperty("url", dataSourceProperties.getUrl());
if (dataSourceProperties.getUsername() != null) {
config.addDataSourceProperty("user", dataSourceProperties.getUsername());
} else {
config.addDataSourceProperty("user", ""); // HikariCP doesn't allow null user
}
if (dataSourceProperties.getPassword() != null) {
config.addDataSourceProperty("password", dataSourceProperties.getPassword());
} else {
config.addDataSourceProperty("password", ""); // HikariCP doesn't allow null password
}
config.setConnectionTimeout(jHipsterProperties.getDatasource().getConnectionTimeout());
config.setMaximumPoolSize(jHipsterProperties.getDatasource().getMaximumPoolSize());
//MySQL optimizations, see https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration
if ("com.mysql.jdbc.jdbc2.optional.MysqlDataSource".equals(dataSourceProperties.getDriverClassName())) {
config.addDataSourceProperty("cachePrepStmts", jHipsterProperties.getDatasource().isCachePrepStmts());
config.addDataSourceProperty("prepStmtCacheSize", jHipsterProperties.getDatasource().getPrepStmtCacheSize());
config.addDataSourceProperty("prepStmtCacheSqlLimit", jHipsterProperties.getDatasource().getPrepStmtCacheSqlLimit());
}
if (metricRegistry != null) {
config.setMetricRegistry(metricRegistry);
}
return new HikariDataSource(config);
}
@Bean
public Hibernate5Module hibernate5Module() {
return new Hibernate5Module();
}
}
@Transactional
throws TransactionRequiredException
: No EntityManager
with actual transaction available for current thread - cannot reliably process persist
when using AspectJ even with compile-time weaving plugin and all AspectJ dependencies and Development tools installed.
Possibly similar question: Why would switching from AspectJ to Proxy mode cause a "TransactionRequiredException: Executing an update/delete query" to no longer occur?
I intend to use AspectJ instead of Spring AOP to increase the performance of my app.
Here I presented part of three files. AspectJ Development Toolkit is installed.
pom.xml:
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.8</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.8</version>
</dependency>
<dependency>
<groupId>dev.aspectj</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.13.1</version>
<type>maven-plugin</type>
</dependency>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<!-- <goal>test-compile</goal> -->
</goals>
</execution>
</executions>
<configuration>
<complianceLevel>17</complianceLevel>
<forceAjcCompile>true</forceAjcCompile>
<weaveDirectories>
<weaveDirectory>${project.build.outputDirectory}</weaveDirectory>
</weaveDirectories>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
</plugin>
</plugins>
</build>
XService.java:
@Service
@Transactional(propagation = Propagation.SUPPORTS)
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class BridgeService {
...
@Transactional
private void persistAvatarResource(String resCode, String start) {
AvatarRes avatarRes = new AvatarRes();
avatarRes.setClient(client);
avatarRes.setAvatar(avatar);
avatarRes.setRes(getResource(resCode));
avatarRes.setStart(PHPHelper.toInt(start));
entityManager.persist(avatarRes);
}
...
}
DatabaseConfig.java:
@Configuration
@EnableJpaRepositories("com.lixar.apba.repository")
@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
public class DatabaseConfiguration {
private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);
@Inject
private Environment env;
@Autowired(required = false)
private MetricRegistry metricRegistry;
@Bean(destroyMethod = "close")
@ConditionalOnExpression("!environment.acceptsProfiles('cloud') && !environment.acceptsProfiles('heroku')")
public DataSource dataSource(DataSourceProperties dataSourceProperties, JHipsterProperties jHipsterProperties, CacheManager cacheManager) {
log.debug("Configuring Datasource");
if (dataSourceProperties.getUrl() == null) {
log.error("Your database connection pool configuration is incorrect! The application" +
" cannot start. Please check your Spring profile, current profiles are: {}",
Arrays.toString(env.getActiveProfiles()));
throw new ApplicationContextException("Database connection pool is not configured correctly");
}
HikariConfig config = new HikariConfig();
config.setDataSourceClassName(dataSourceProperties.getDriverClassName());
config.addDataSourceProperty("url", dataSourceProperties.getUrl());
if (dataSourceProperties.getUsername() != null) {
config.addDataSourceProperty("user", dataSourceProperties.getUsername());
} else {
config.addDataSourceProperty("user", ""); // HikariCP doesn't allow null user
}
if (dataSourceProperties.getPassword() != null) {
config.addDataSourceProperty("password", dataSourceProperties.getPassword());
} else {
config.addDataSourceProperty("password", ""); // HikariCP doesn't allow null password
}
config.setConnectionTimeout(jHipsterProperties.getDatasource().getConnectionTimeout());
config.setMaximumPoolSize(jHipsterProperties.getDatasource().getMaximumPoolSize());
//MySQL optimizations, see https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration
if ("com.mysql.jdbc.jdbc2.optional.MysqlDataSource".equals(dataSourceProperties.getDriverClassName())) {
config.addDataSourceProperty("cachePrepStmts", jHipsterProperties.getDatasource().isCachePrepStmts());
config.addDataSourceProperty("prepStmtCacheSize", jHipsterProperties.getDatasource().getPrepStmtCacheSize());
config.addDataSourceProperty("prepStmtCacheSqlLimit", jHipsterProperties.getDatasource().getPrepStmtCacheSqlLimit());
}
if (metricRegistry != null) {
config.setMetricRegistry(metricRegistry);
}
return new HikariDataSource(config);
}
@Bean
public Hibernate5Module hibernate5Module() {
return new Hibernate5Module();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论