Spring JPA:从Async方法处理时,数据未保存到数据库

时间:2017-08-04 10:58:52

标签: spring hibernate spring-boot spring-data spring-data-jpa

我有一个使用Spring JPA的应用程序,并使用@Async spring注释执行一些后台进程。该过程需要保存数据库中的参数,或者如果已存在则更新数据库。

这并不能正常工作,因为@Async方法完成后我的数据实体不会在数据库中保留。但是当我从方法中删除@Async注释时,一切正常。我的数据已保存或更新为DB。

有没有人知道可能出现什么问题或者我可能错过了什么?

感谢。

**更新[代码示例]

ASYNCSERVICE

@Service
@EnableAsync
class AsyncService() {
    @Async
    public void process(firstEntity, secondEntity) {
        firstEntity = prepareParams(firstEntity);
        secondEntity = prepareParams(secondEntity);
        save(firstEntity, secondEntity);
    }
}

ENTITYRELATIONSERVICE

@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 CONFIG

@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;
}

1 个答案:

答案 0 :(得分:1)

我猜测@Async方法和@Transactional属于同一个类。

Be ware:@Async将创建一个不会是事务性的新线程(因此不会在DB中写入)。使用Spring代理的东西,你的异步方法需要在另一个类上调用一个方法才能让@Transactional返回。

换句话说,使用@Async方法创建一个新的空类,该方法只调用原始类中的main方法(具有@Transactional)。