【问题标题】:Spring MVC application not synchronizedSpring MVC 应用程序未同步
【发布时间】:2017-05-18 04:53:49
【问题描述】:

在我的 Spring MVC 应用程序中,我们遇到了以下问题。我们是 spring 新手并使用 spring 3.x。将在下面解释问题,如果不清楚,请发表评论。

  • 当我们同时触发并发请求到下面的服务和 Repository bean,下面代码中显示的 SampleBean 对象正在获取 被稍后触发的请求覆盖。

  • 换句话说,线程 1 中 SampleBean 的值正在获取
    在线程 2 中被 SampleBean 的值覆盖。

使用cmets的骨架代码如下。

MyService.java

@Service public class MyService {
        @Autowired  private SampleBean sampleBean;
        @Autowired  private MyDao myDao;
        public void updateDetailsToDB() throws Exception {
           sampleBean.setXXX("xxx");
           sampleBean.setYYY("yyy");
           myDao.updateDetailsToDB(sampleBean);
        }
    }

MyDao.java

@Repository 
public class MyDao {
    @Autowired  private SampleBean sampleBean;
    @Autowired  private MyDao myDao;
    public void updateDetailsToDB(SampleBean sampleBean) throws Exception {
       //Step 1: Print the data in sampleBean to console - *At this point the the sampleBean object prints the correct value specific to the thread.*
       //Step 2: Insert data to table 1 into db using **jdbcTemplate**, the data will be taken from the bean 
         sampleBean getters.
       //Step 3: Print the data in sampleBean to console.- *At this point the sampleBean value always print the values of the second request and it overwrites the value of the bean in first request as well which is not the case in Step 1.*
       //Step 4: Insert data to table 2
    }
}

更新: 如果我将 synchronized 添加到服务类中的方法中,那么随着请求被一一处理,每一件事都可以正常工作。如何在不添加同步的情况下解决此问题。

【问题讨论】:

  • 你不应该把状态保持在一个单例中,你的设计是有缺陷的。你的SampleBean 不应该在那里。它应该只作为方法参数存在,最好用 @ModelAttribute 注释。

标签: java spring multithreading spring-mvc thread-safety


【解决方案1】:

MyService 中的@Service 默认是单例的,SampleBean 也是如此。您可以尝试将 SampleBean 范围从单例更改为另一个。也许更好的方法是不使用 SampleBean 的实例变量,而是为 MyService 的每个 updateDetailsToDB 方法请求创建一个新实例。 --谢谢郝志

【讨论】:

    【解决方案2】:

    实际上您的设计是错误的,因为您使用的是实例变量。 但是在您的 MyService 类中使用 @Scope("prototype") 或 @Scope("request") (如果它是 Web 应用程序)可以使其工作。

    【讨论】:

    • 因为我在 MyService 中使用 @Service 默认情况下它会是单例的,对吧?
    • @prabu 你是对的。 MyService 中的 @Service 默认是单例的,SampleBean 也是如此。您可以尝试将 SampleBean 范围从单例更改为另一个。也许更好的方法是不使用 SampleBean 的实例变量,而是为 MyService 的每个updateDetailsToDB 方法请求创建一个新实例。
    猜你喜欢
    • 2015-10-27
    • 2014-12-26
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 2011-03-16
    • 2017-12-25
    • 2023-03-16
    • 2011-03-07
    相关资源
    最近更新 更多