简体   繁体   English

Java服务层中的多线程

[英]Multithreading in Service layer in Java

I am designing web app with Spring MVC. 我正在使用Spring MVC设计Web应用程序。

I have some problem in implementing safely updating e-mail and registering new user. 我在实施安全更新电子邮件和注册新用户时遇到一些问题。 E-mail is unique for every user. 电子邮件对于每个用户都是唯一的。

It is my method, which is invoked by controller for registering user: 这是我的方法,由控制器调用以注册用户:

@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);


    }

It is method for updating email: 它是更新电子邮件的方法:

@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);
    }

There is can be situation, when some user clicks button for registering, registerUser(Client newUser) method checks email for uniqueness, at the same moment second user want to update email, and before clientDao.save(newUser) is invoked, updateUserEmail(String email, String newEmail, String password) checks email for uniqueness, and if emails of both users are equals, I will get two the same emails in db - it is unacceptable. 可能存在这样的情况,当某些用户单击注册按钮时, registerUser(Client newUser)方法检查电子邮件的唯一性,同时第二个用户要更新电子邮件,并且在调用clientDao.save(newUser)之前, updateUserEmail(String email, String newEmail, String password)检查电子邮件的唯一性,如果两个用户的电子邮件相等,我将在db中收到两个相同的电子邮件-这是不可接受的。

My Service layer is marked with @Translactional annotation, session is automatically flushed before closing transaction, and user is saved in db only after finishing registerUser(..) method 我的服务层标记有@Translactional批注,会话在关闭事务之前自动刷新,并且仅在完成registerUser(..)方法后,用户才保存在db中

So, tell me please, which instruments in Java multithreading can I use for solving this problem? 那么,请告诉我,我可以使用Java多线程中的哪些工具来解决此问题?

You can do this programmatically by rolling the isEmailUnique method into the save functionality and making the save method synchronized. 您可以通过将isEmailUnique方法滚动到保存功能中并使该save方法同步来以编程方式执行此操作。

BUT the better solution is to make the email column have a unique constraint in the db, to make sure that no duplicates can ever make it into your dataset no matter where in the app, or even which app, they come from. 但是更好的解决方案是使email列在数据库中具有唯一的约束,以确保无论应用来自何处,甚至来自哪个应用,都不会将重复项放入您的数据集中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM