2016-08-04 42 views
1

我正在用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中的多線程爲了解決這個問題?

回答

4

您可以通過將isEmailUnique方法滾動到保存功能並使save方法同步來以編程方式執行此操作。

更好的解決辦法是讓電子郵件列有一個唯一約束在DB,以確保沒有重複都不能讓它進入你的數據集無論身在何處的應用程序,或者甚至是應用程序,它們來自。

+0

但在我更新的電子郵件方法中,我沒有使用save方法,我從db獲取Client實例並在此持久實例上設置字段。 – Yuriy

+0

處理唯一性問題是您真正想避免在應用程序中執行的事情,如果您可以管理它。這是因爲即使您在一個JVM中解決了併發問題,如果您橫向擴展到應用程序的多個實例,您現在需要管理多個應用程序之間的併發性,這可能是一個非常難以解決的問題。我強烈建議你在DB端處理這個問題。 –

+0

因此,我捕獲異常,如果我嘗試保存具有重複電子郵件的對象,則會調用異常。謝謝:) – Yuriy