2016-01-13 49 views
1

我在網站上工作,人們可以通過點擊觸發AJAX POST請求的鏈接訂閱錦標賽。 該應用程序是使用Spring MVC和Hibernate構建的。用戶雙擊一個按鈕後在數據庫中雙插入

有時候,當用戶雙擊時,他會在數據庫中註冊兩次。 我試圖把一些JavaScript安全,但它似乎還不夠。

所以我猜,兩個請求幾乎同時播放,第二個請求在第一個請求被保存到數據庫之前通過isUserAlreadySubscribed測試。

有沒有一種方法與Hibernate在這種特定的方法上放置一種標記?也許與會議有關?

下面,控制器調用的服務方法。

@Override 
@Transactional 
public boolean joinTournament(String username, Long eventId, String date, Long barId) { 
     [... check if tournament exists ...] 
     if (!isUserAlreadySubscribed(tournament, username)) { 
      //On enregistre le user comme inscrit 
      TournamentPlayer tournamentPlayer = new TournamentPlayer(); 
      tournamentPlayer.setPresent(false); 
      tournamentPlayer.setTournament(tournament); 
      com.meltdown.users.domain.User user = hibernateUserDao.findByUsername(username); 
      tournamentPlayer.setUser(user); 
      java.util.Date today = new java.util.Date(); 
      tournamentPlayer.setCreatedAt(new Timestamp(today.getTime())); 
      hibernateTournamentDao.createTournamentPlayer(tournamentPlayer); 
      tournament.getPlayers().add(tournamentPlayer); 

      hibernateTournamentDao.editTournament(tournament); 

      [... send mail ...] 
      return true; 
     } 
    return false; 
} 
+0

你使用JPA實體類嗎?如果是,那麼您是使用版本註釋還是版本字段(http://docs.oracle.com/javaee/6/api/javax/persistence/Version.html)? – Rozart

+0

我使用JPA實體但不是@Version註釋 – Labe

回答

2

看起來您已經在使用聲明式事務管理和Transactional註釋。所以你可能想看看你想用什麼isolation level。就像一個測試,看看是否能解決您的問題,您可以更改該方法使用最嚴格的隔離:

@Transactional(isolation=Isolation.SERIALIZABLE) 

如果成功,可以降級到更高性能的水平,如READ_COMMITTED

+0

看起來不錯!我會嘗試並讓你知道。謝謝 – Labe

+0

我無法降低隔離強度 – Labe

+1

@Labe - 可能想修復你的javascript下一個 – david