我有一个使用 Spring JPA 的应用程序,并使用 @Async spring 注释执行一些后台进程。该过程需要将参数保存在数据库中,或者如果已经存在,则更新数据库。
这不起作用,因为在
@Async
方法完成后,我的数据实体没有保留在数据库中。但是当我从方法中删除 @Async
注释时,一切工作正常。我的数据已保存或更新在数据库中。
有人知道可能出了什么问题或者我可能错过了什么吗?
谢谢。
** 更新[代码示例]
异步服务
@Service
@EnableAsync
class AsyncService() {
@Async
public void process(firstEntity, secondEntity) {
firstEntity = prepareParams(firstEntity);
secondEntity = prepareParams(secondEntity);
save(firstEntity, secondEntity);
}
}
实体关系服务
@Transactional
@Service
class EntityRelationService() {
private SecondEntityRepo secondEntityRepo;
@Autowired
public EntityRelationService(SecondEntityRepo secondEntityRepo) {
this.secondEntityRepo = secondEntityRepo;
}
@Transactional
public void save(p1, p2) {
p2.setRelation(p1);
this.secondEntityRepo(p2);
}
}
Bean 配置
@Bean
@Primary
@ConfigurationProperties(prefix = "app.database")
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
@Bean
@Primary
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sf = new LocalSessionFactoryBean();
sf.setDataSource(dataSource());
sf.setPackagesToScan("com.app");
Properties props = new Properties();
props.put("hibernate.use_sql_comments", false);
props.put("hibernate.show_sql", true);
sf.setHibernateProperties(props);
return sf;
}
@Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager =
new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
我猜测 @Async 方法与 @Transactional 位于同一类中。
注意:@Async 将创建一个不是事务性的新线程(因此不会写入数据库)。使用Spring代理的东西,你的异步方法需要调用另一个类上的方法才能恢复@Transactional。
换句话说,使用 @Async 方法创建一个新的空类,该方法仅调用原始类(具有 @Transactional)中的 main 方法。
一个简单的例子如下所示:
真实服务的代理:
@Service
@EnableAsync
class AsyncService() {
private SyncService syncService;
@Async
public void process(String param) {
syncService.process(param);
}
}
真正的服务:
@Service
@Transactional
class SyncService() {
public void process(String param) {
// ... Do whatever you want
}
}
我也有类似的问题: 每当方法 (A) 引发异常时,所有更改都会回滚。此外,从方法 (A) 调用的其他方法内发生的所有更改都会回滚。
我的解决方案是将以下注释放在一个方法上,无论其他地方发生什么,我都确保始终保存对象:
import org.springframework.transaction.annotation.Transactional;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void doStuff() {
...
}