gpt4 book ai didi

java - 带有 mode = AdviceMode.ASPECTJ 的 Spring Transaction 无法正常工作

转载 作者:行者123 更新时间:2023-12-02 03:07:05 25 4
gpt4 key购买 nike

我知道 Spring 事务默认使用 mode = AdviceMode.PROXY,但我们没有机会在一个服务内打开新事务。此问题已通过 mode = AdviceMode.ASPECTJ 修复。但我的代码无法使用此属性正常工作。

配置:

@Configuration
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
@EnableJpaRepositories(
entityManagerFactoryRef = "mysqlEntityManagerFactory",
transactionManagerRef = "mysqlTransactionManager",
basePackages = {"softserve.spring.com.repository"}
)
public class TransactionConfig {

@Bean(name = "mysqlDataSource")
@ConfigurationProperties(prefix = "mysql.datasource")
public DataSource dataSource() {
return DataSourceBuilder
.create()
.build();
}

@Bean(name = "mysqlEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("mysqlDataSource") DataSource dataSource
) {
return builder
.dataSource(dataSource)
.packages("softserve.spring.com.entity")
.persistenceUnit("mysql")
.build();
}

@Bean(name = "mysqlTransactionManager")
public PlatformTransactionManager mysqlTransactionManager(
@Qualifier("mysqlEntityManagerFactory") EntityManagerFactory mysqlEntityManagerFactory
) {
return new JpaTransactionManager(mysqlEntityManagerFactory);
}

}

属性:

spring.jpa.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=false

mysql.datasource.jdbc-url=jdbc:mysql://localhost:3306/db_transaction?useSSL=false&useUnicode=yes&characterEncoding=UTF-8
mysql.datasource.username=root
mysql.datasource.password=root
mysql.datasource.driver-class-name=com.mysql.jdbc.Driver

服务:

@Service
public class UserService {

@Autowired
private UserRepository userrepository;

@Transactional
public void createUsers() {
create();

User user = new User("B", 0);
userrepository.save(user);

throw new RuntimeException();
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void create() {
User user = new User("A", 100);
userrepository.save(user);
}

@Transactional
public void deleteAll() {
userrepository.deleteAll();
}

}

执行此代码后数据库中必须有一个用户。但我有两个。如何正确设置?

最佳答案

使用代理时,您必须了解在调用 this 上的方法时会发生什么(以及不会发生什么),就像使用 create() 所做的那样。阅读 the documentation了解为什么 this 不是事务处理 bean:

However, once the call has finally reached the target object (the SimplePojo, reference in this case), any method calls that it may make on itself, such as this.bar() or this.foo(), are going to be invoked against the this reference, and not the proxy. This has important implications. It means that self-invocation is not going to result in the advice associated with a method invocation getting a chance to execute.

但是,当使用 AspectJ 时,类的字节码与事务处理方面交织在一起,因此即使调用 this 也能按预期工作。

关于java - 带有 mode = AdviceMode.ASPECTJ 的 Spring Transaction 无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57017900/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com