2016-01-13 52 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