我正在使用 Spring MVC 设计 Web 应用程序。
我在实现安全更新电子邮件和注册新用户时遇到了一些问题。 每个用户的电子邮件都是唯一的。
这是我的方法,由 Controller 调用以注册用户:
@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)
检查电子邮件的唯一性,如果两个用户的电子邮件相等,我会得到两个数据库中的相同电子邮件 - 这是 Not Acceptable 。
我的服务层用@Translactional
注解标记,session在关闭事务前自动刷新,用户在完成registerUser(..)
方法后才保存在db中
请告诉我,我可以使用 Java 多线程中的哪些工具来解决这个问题?
最佳答案
您可以通过将 isEmailUnique 方法滚动到保存功能并使保存方法同步来以编程方式执行此操作。
但是 更好的解决方案是使电子邮件列在数据库中具有唯一约束,以确保无论在应用程序的哪个位置,甚至它们来自哪个应用程序。
关于java - Java服务层中的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38773013/