简体   繁体   English

Spring Async用于批量插入

[英]Spring Async for batch insertion

I'm using spring boot. 我正在使用弹簧靴。 I was new to spring and started a spring project. 我刚接触春季,并开始了春季项目。 So I didn't know about pre defined repositories (JPA, CRUD) which can be easily implemented. 因此,我不知道可以轻松实现的预定义存储库(JPA,CRUD)。 In case, I wanted to save a bulk data, so I use for loop and save one by one, Its taking more time. 以防万一,我想保存大量数据,所以我使用for循环并一个一个地保存,这需要更多时间。 So I tried to use @Async . 所以我尝试使用@Async But it doesn't also work, is my concept wrong? 但这也不起作用,我的概念错了吗?

@Async has two limitation @Async有两个限制

  • it must be applied to public methods only 它只能应用于公共方法
  • self-invocation – calling the async method from within the same class won't work 自我调用–从同一个类中调用async方法将不起作用

1) Controller 1)控制器

for(i=0;i < array.length();i++){
    // Other codes
    gaugeCategoryService.saveOrUpdate(getEditCategory);
}

2) Dao implementation 2)实施

@Repository
public class GaugeCategoryDaoImpl implements GaugeCategoryDao {
    // Other codings

    @Async
    @Override   
    public void saveOrUpdate(GaugeCategory GaugeCategory) {
        sessionFactory.getCurrentSession().saveOrUpdate(GaugeCategory);
    }
}

After removing @Async , it working normally. 删除@Async后,它可以正常工作。 But with that annotation it doesn't work. 但是,使用该注释将不起作用。 Is there any alternative method for time consuming? 有其他替代方法可以节省时间吗? Thanks in advance. 提前致谢。

the @Async annotation creates a thread for every time you call that method. @Async注释会在您每次调用该方法时创建一个线程。 but you need to enable it in your class using this annotation @EnableAsync You also need to configure the asyncExecutor Bean. 但是您需要使用@EnableAsync注释在您的类中启用它。您还需要配置asyncExecutor Bean。 You can find more details here : https://spring.io/guides/gs/async-method/ 您可以在这里找到更多详细信息: https : //spring.io/guides/gs/async-method/

In my opinion, there are several issues with your code: 我认为您的代码有几个问题:

  1. You overwrite the saveOrUpdate() method without any need to do so. 您可以覆盖saveOrUpdate()方法,而无需这样做。 A simple call to "super()" should have been enough to make @Async work. 一个简单的“ super()”调用就足以使@Async工作。

  2. I guess that you somewhere (within your controller class?) declare a transactional context. 我猜你在某个地方(在控制器类中?)声明了一个事务上下文。 That one usually applies to the current thread. 那通常适用于当前线程。 By using @Async, you might leave this transaction context as (because of the async DAO execution), the main thread may already be finished when saveOrUpdate() is called. 通过使用@Async,您可以将此事务上下文保留为(由于执行异步DAO),因此在调用saveOrUpdate()时主线程可能已经完成。 And even though I currently don't know it exactly, there is a good change that the declared transaction is only valid for the current thread. 即使我目前尚不清楚,但还是有一个很好的变化,即声明的事务仅对当前线程有效。

One possble fix: create an additional component like AsyncGaugeCategoryService or so like this: 一种可能的解决方法:创建一个其他组件,例如AsyncGaugeCategoryService或类似的代码:

@Component
public class AsyncGaugeCategoryService {

    private final GaugeCategoryDao gaugeCategoryDao;

    @Autowired
    public AsyncGaugeCategoryService(GaugeCategoryDao gaugeCategoryDao) {
        this.gaugeCategoryDao = gaugeCategoryDao;
    }

    @Async
    @Transactional
    public void saveOrUpdate(GaugeCategory gaugeCategory) {
        gaugeCategoryDao.saveOrUpdate(gaugeCategory);
    }
}

Then inject the service instead of the DAO into your controller class. 然后将服务而不是DAO注入到您的控制器类中。 This way, you don't need to overwrite any methods, and you should have a valid transactional context within your async thread. 这样,您无需覆盖任何方法,并且异步线程中应该具有有效的事务上下文。

But be warned that your execution flow won't give you any hint if something goes wrong while storing into the database. 但请注意,如果在存储到数据库中时出现问题,执行流不会给您任何提示。 You'll have to check the log files to detect any problems. 您必须检查日志文件以检测任何问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM