用户双击按钮后在数据库中双重插入

时间:2016-01-13 17:59:06

标签: java hibernate spring-mvc

我在网站上工作,人们可以通过点击触发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;
}

1 个答案:

答案 0 :(得分:2)

看起来您已经在使用带有SELECT app.ID as 'AppraisalID', app.CityName, app.CountryName, app.Street, app.DateCreated, subApp.ID as 'SubAppraisalID', subApp.Message, subApp.DateCreated From ( SELECT TOP 10 dbo.Appraisal.ID, dbo.Appraisal.Street, dbo.Country.Name as 'CountryName', dbo.City.Name as 'CityName', dbo.Appraisal.DateCreated FROM dbo.Appraisal INNER JOIN dbo.Country ON dbo.Appraisal.CountryID = dbo.Country.ID INNER JOIN dbo.City ON dbo.Appraisal.CityID = dbo.City.ID Order by dbo.Appraisal.DateCreated DESC ) app Cross Join ( SELECT TOP 10 dbo.Sub_Appraisal.ID, dbo.Sub_Appraisal.Message, dbo.Sub_Appraisal.DateCreated FROM dbo.Sub_Appraisal Order by dbo.Sub_Appraisal.DateCreated DESC ) subApp Order By app.DateCreated DESC, subApp.DateCreated DESC 注释的声明式事务管理。所以你可能想看一下你想要使用的isolation level。就像测试它是否能解决您的问题一样,您可以更改该方法以使用最严格的隔离:

response = gbq_service->jobs->getQueryResults($project_id, $jobId, array('timeoutMs' => 100000, 'maxResults'=>1000));

如果成功,您可以降级到更高效的级别,例如Transactional