diff --git a/src/main/java/com/moing/backend/domain/boardRead/domain/repository/BoardReadRepository.java b/src/main/java/com/moing/backend/domain/boardRead/domain/repository/BoardReadRepository.java index 0053ac5b..2be1ae98 100644 --- a/src/main/java/com/moing/backend/domain/boardRead/domain/repository/BoardReadRepository.java +++ b/src/main/java/com/moing/backend/domain/boardRead/domain/repository/BoardReadRepository.java @@ -5,10 +5,14 @@ import com.moing.backend.domain.member.domain.entity.Member; import com.moing.backend.domain.team.domain.entity.Team; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Lock; +import javax.persistence.LockModeType; import java.util.List; import java.util.Optional; public interface BoardReadRepository extends JpaRepository { + + @Lock(LockModeType.PESSIMISTIC_WRITE) List findBoardReadByBoardAndMemberAndTeam(Board board, Member member, Team team); } diff --git a/src/main/java/com/moing/backend/domain/boardRead/domain/service/BoardReadSaveService.java b/src/main/java/com/moing/backend/domain/boardRead/domain/service/BoardReadSaveService.java index c15ca2c7..563cc991 100644 --- a/src/main/java/com/moing/backend/domain/boardRead/domain/service/BoardReadSaveService.java +++ b/src/main/java/com/moing/backend/domain/boardRead/domain/service/BoardReadSaveService.java @@ -16,16 +16,15 @@ public class BoardReadSaveService { private final BoardReadRepository boardReadRepository; + public void saveBoardRead(Board board, BoardRead boardRead) { - List existingBoardReads = boardReadRepository.findBoardReadByBoardAndMemberAndTeam(board, boardRead.getMember(), boardRead.getTeam()); + synchronized (this) { + List existingBoardReads = boardReadRepository.findBoardReadByBoardAndMemberAndTeam(board, boardRead.getMember(), boardRead.getTeam()); - if (existingBoardReads.size() > 1) { - // 첫 번째 엔티티를 제외하고 나머지 삭제 - List duplicates = existingBoardReads.subList(1, existingBoardReads.size()); - boardReadRepository.deleteAll(duplicates); - } else if (existingBoardReads.isEmpty()) { - boardRead.updateBoard(board); - boardReadRepository.save(boardRead); + if (existingBoardReads.isEmpty()) { + boardRead.updateBoard(board); + boardReadRepository.save(boardRead); + } } } } diff --git a/src/main/java/com/moing/backend/domain/statistics/application/service/DAUScheduleUseCase.java b/src/main/java/com/moing/backend/domain/statistics/application/service/DAUScheduleUseCase.java index c002f123..4d2ca7f7 100644 --- a/src/main/java/com/moing/backend/domain/statistics/application/service/DAUScheduleUseCase.java +++ b/src/main/java/com/moing/backend/domain/statistics/application/service/DAUScheduleUseCase.java @@ -35,7 +35,7 @@ public class DAUScheduleUseCase { /* DAU 정보 : 일일 모임 생성 수, 일일 신규 가입자 수, 일일 반복 미션 생성 수, 일일 한번 미션 생성 수 */ - @Scheduled(cron = "0 59 23 * * *") + @Scheduled(cron = "0 55 23 * * *") public void DailyTeamCreationInfoAlarm() { Map todayStats = new LinkedHashMap<>(); Map yesterdayStats = new LinkedHashMap<>(); diff --git a/src/main/java/com/moing/backend/domain/teamMember/domain/repository/TeamMemberRepository.java b/src/main/java/com/moing/backend/domain/teamMember/domain/repository/TeamMemberRepository.java index 42d665b9..503cd5bb 100644 --- a/src/main/java/com/moing/backend/domain/teamMember/domain/repository/TeamMemberRepository.java +++ b/src/main/java/com/moing/backend/domain/teamMember/domain/repository/TeamMemberRepository.java @@ -4,13 +4,16 @@ import com.moing.backend.domain.team.domain.entity.Team; import com.moing.backend.domain.teamMember.domain.entity.TeamMember; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Lock; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; +import javax.persistence.LockModeType; import javax.swing.text.html.Option; import java.util.Optional; public interface TeamMemberRepository extends JpaRepository, TeamMemberCustomRepository{ - Optional findTeamMemberByTeamAndMember(Team team, Member member); + @Lock(LockModeType.PESSIMISTIC_WRITE) + Optional findTeamMemberByTeamAndMember(Team team, Member member); } diff --git a/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java b/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java index 94830dd3..a1a7090b 100644 --- a/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java +++ b/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java @@ -19,14 +19,14 @@ public class TeamMemberSaveService { private final TeamMemberRepository teamMemberRepository; public void addTeamMember(Team team, Member member) { - Optional teamMember = teamMemberRepository.findTeamMemberByTeamAndMember(team, member); - - checkDeletion(team); - - if (teamMember.isPresent()) { - handleExistingMember(teamMember.get()); - } else { - addNewTeamMember(team, member); + synchronized (this) { + Optional teamMember = teamMemberRepository.findTeamMemberByTeamAndMember(team, member); + checkDeletion(team); + if (teamMember.isPresent()) { + handleExistingMember(teamMember.get()); + } else { + addNewTeamMember(team, member); + } } } diff --git a/src/main/java/com/moing/backend/global/config/slack/exception/ExceptionEventHandler.java b/src/main/java/com/moing/backend/global/config/slack/exception/ExceptionEventHandler.java index 877decdc..857523f8 100644 --- a/src/main/java/com/moing/backend/global/config/slack/exception/ExceptionEventHandler.java +++ b/src/main/java/com/moing/backend/global/config/slack/exception/ExceptionEventHandler.java @@ -3,12 +3,14 @@ import com.moing.backend.global.config.slack.exception.dto.ExceptionEvent; import com.moing.backend.global.config.slack.util.WebhookUtil; import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Profile; import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; @RequiredArgsConstructor @Component +@Profile("prod") public class ExceptionEventHandler { private final WebhookUtil webhookUtil;