我知道默认情况下,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();
}
}
执行此代码后,数据库中必须是一个用户。但是我有两个。如何正确设置?
答案 0 :(得分:0)
使用代理时,您必须知道在this
上调用方法时会发生什么(什么不会发生),就像使用create()
一样。
阅读the documentation,了解为什么this
不是事务处理bean:
但是,一旦调用最终到达目标对象(在本例中为SimplePojo,则为引用),它可能对其自身进行的任何方法调用(例如this.bar()或this.foo())都会进行将针对此引用而不是代理进行调用。这具有重要的意义。这意味着自调用不会导致与方法调用相关的建议得到执行的机会。
但是,在使用AspectJ时,类的字节码是与事务处理方面交织在一起的,因此即使对this
的调用也可以按预期工作。