Spring中实例DAO与Singelton Bean的交互

时间:2018-09-06 04:48:51

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

假设我有一个名为Assignment的DAO,它使用@Document映射声明了一个mongo集合名称Assignment。

然后,我有一个服务bean,例如AssigmentImpl,它在单例范围内,执行更新操作,在其中获取持久化的DAO,并使用REST输入数据进行赋值更新。

@Service
public class AssignmentImpl{    
public Assignment updateAssignment(Assignment assignment){
    Assignment assignmentExsisting  = assignmentRepo.getAssignment(assignment.getId());
    BeanUtils.copyProperties(assignment,assignmentExsisting);
    assignmentRepo.save(assignmentExsisting);    
}    
}

假设有多个线程(用户)对不同的分配执行更新操作。

AssignmentService是单例的,它将向不同的用户返回相同的副本。它如何引用工作分配对象?如果我说,由于Assignment对象不是单例的,那么当每个用户执行更新操作时,它将向AssignmentImpl返回不同的对象引用,对吗?

在这种情况下,用户A可能会在执行更新操作之前获得分配ID 123,而在用户B开始执行更新操作时,AssignmentImpl会将分配引用更改为其他分配ID456。在这种情况下,用户A将更新完全不同的分配。有可能吗?如果可以,我们如何预防呢?使更新操作同步还是有其他好的解决方案?

1 个答案:

答案 0 :(得分:1)

不,这不是您的想法,请注意,即使服务类也很重要,每个更新调用都不会与其他任何方法调用的执行重叠,因为两者都将在服务器创建的不同线程中执行。因此,该操作将按照给定的分配进行,并且两个用户的结果不会互换,为什么?,因为每个线程都独立执行方法,但是当两个线程尝试修改状态时会出现问题共享元素的数量,即在服务方法中的类级别声明的对象的更改值。

例如,有两辆巴士从A点出发到B点。现在,没有一辆巴士共享乘客(不可能吗?),它们都有自己的乘客和燃料,但是机制(存储库和服务) ),两辆公交车都保持不变。

据我所知,您看到两个线程在这里没有共享任何东西,是的,它使用了存储库bean,但是它没有修改它的状态,它只会将分配发送到存储区,并通过id来检索分配。