我正在用Spring MVC设计web应用程序。Java中服务层的多线程
我在安全更新电子邮件和注册新用户时遇到了一些问题。 电子邮件对每个用户都是唯一的。
这是我的方法,它是由控制器用于注册用户调用:
@Override
public void registerUser(Client newUser) throws DuplicateEmailException {
if(!isEmailUnique(newUser.getEmail())){
throw new DuplicateEmailException("User with the same email is registered"
+ " in system already");
}
newUser.setPassword(encodePassword(newUser.getPassword()));
newUser.setRole(UserRole.ROLE_CLIENT);
newUser.setStatus(UserStatus.ACTIVE);
newUser.setEmailStatus(EmailStatus.NOTCONFIRMED);
newUser.setRegistrationTime(LocalDateTime.now());
clientDao.save(newUser);
}
这是更新的电子邮件方法:
@Override
public void updateUserEmail(String email, String newEmail, String password)
throws InvalidPasswordException, DuplicateEmailException {
Client client = getClientByEmail(email);
if(!isPasswordRight(password, client.getPassword())){
throw new InvalidPasswordException("Password doesn't match to real");
}
if(email.equals(newEmail)){
return;
}
if(!isEmailUnique(newEmail)){
throw new DuplicateEmailException(
"Such email is registered in system already");
}
client.setEmail(newEmail);
client.setEmailStatus(EmailStatus.NOTCONFIRMED);
}
有可能的情况下,当某些用户点击按钮对于注册,registerUser(Client newUser)
方法检查电子邮件的唯一性,同时第二个用户想要更新电子邮件,并且在clientDao.save(newUser)
被调用之前,updateUserEmail(String email, String newEmail, String password)
检查电子邮件的唯一性,如果两个用户的电子邮件是平等的,我会g等两个相同的电子邮件在db - 这是不可接受的。
我的服务层都标有@Translactional
注解,会话自动关闭交易之前冲刷和用户保存在数据库整理registerUser(..)
方法
所以以后只,请告诉我,我可以使用哪些工具在Java中的多线程为了解决这个问题?
但在我更新的电子邮件方法中,我没有使用save方法,我从db获取Client实例并在此持久实例上设置字段。 – Yuriy
处理唯一性问题是您真正想避免在应用程序中执行的事情,如果您可以管理它。这是因为即使您在一个JVM中解决了并发问题,如果您横向扩展到应用程序的多个实例,您现在需要管理多个应用程序之间的并发性,这可能是一个非常难以解决的问题。我强烈建议你在DB端处理这个问题。 –
因此,我捕获异常,如果我尝试保存具有重复电子邮件的对象,则会调用异常。谢谢:) – Yuriy