读取操作在插入操作完成之前开始。

huangapple 未分类评论54阅读模式
标题翻译

Read starts before the insert completes

问题

    @Transactional
    public void save(String myIds) 
    {
        synchronized (this) 
        {
            List<mydata> data = getDataToSaveOrUpdate(myIds);//Returns the new dataList and updates old data
            repository.saveAll(data);
            logger.info("request processed");
        }
        logger.debug("exiting the method");
    }

在这个方法中,如果我发送两个相同的请求,时间间隔为0.5秒,那么在前一个请求的saveAll完成之前,getDataToSaveOrUpdate方法会开始从repository中读取数据。

注意:我注意到一件事,一旦我移除了 @Transactional,它将正常工作。

英文翻译
@Transactional
    public void save(String myIds) 
    {
            synchronized (this) 
            {
                List&lt;mydata&gt; data = getDataToSaveOrUpdate(myIds);//Returns the new dataList and updates old data
                repository.saveAll(data);
                logger.info(&quot;request processed&quot;);
            }
        logger.debug(&quot;exiting the method&quot;);
    }

In this method if i sent the two same request with the difference between 0.5 sec what happens getDataToSaveOrUpdate method start reading data from repository before the previous request saveAll finishes the job.

Note One thing i noticed that it will work properly once i removed @Transactional

答案1

得分: -1

可能你需要的是 LockModeType(PESSIMISTIC_WRITE)

英文翻译

Maybe what you need is LockModeType(PESSIMISTIC_WRITE).

答案2

得分: -1

第二个请求的处理会在第一个线程退出同步块后立即开始。此时事务可能仍未提交。事务将仅在方法执行完成后才会被提交。

一种可能的解决方案是将synchronized关键字添加到方法本身。

@Transactional
public synchronized void save(String myIds) {    
    List<mydata> data = getDataToSaveOrUpdate(myIds);//返回新的数据列表并更新旧数据
    repository.saveAll(data);
    logger.info("请求已处理");
    logger.debug("退出方法");
}

在使用synchronized关键字时需要非常小心。我不清楚您的确切需求,也许在您的情况下这是一个有效的用法。

英文翻译

Second request processing starts as soon as first thread exits synchronized block. Transaction might still not be committed by then. Transaction will only be committed after method execution is completed.

One possible solution is to add synchronized keyword to the method itself.

@Transactional
public synchronized void save(String myIds) {    
	List&lt;mydata&gt; data = getDataToSaveOrUpdate(myIds);//Returns the new dataList and updates old data
	repository.saveAll(data);
	logger.info(&quot;request processed&quot;);
	logger.debug(&quot;exiting the method&quot;);
}

One need to be very careful when using synchronized keyword. I don't know your exact need, may be it is a valid usage for your scenario.

huangapple
  • 本文由 发表于 2020年5月30日 18:37:56
  • 转载请务必保留本文链接:https://java.coder-hub.com/62101211.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定