Skip to content

Commit

Permalink
Merge pull request #191 from Modagbul/main
Browse files Browse the repository at this point in the history
[release] 동시성 문제 버그 해결
  • Loading branch information
minsu20 authored Jan 5, 2024
2 parents 1878985 + b5df456 commit 93c4f16
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<BoardRead, Long> {

@Lock(LockModeType.PESSIMISTIC_WRITE)
List<BoardRead> findBoardReadByBoardAndMemberAndTeam(Board board, Member member, Team team);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,15 @@ public class BoardReadSaveService {

private final BoardReadRepository boardReadRepository;


public void saveBoardRead(Board board, BoardRead boardRead) {
List<BoardRead> existingBoardReads = boardReadRepository.findBoardReadByBoardAndMemberAndTeam(board, boardRead.getMember(), boardRead.getTeam());
synchronized (this) {
List<BoardRead> existingBoardReads = boardReadRepository.findBoardReadByBoardAndMemberAndTeam(board, boardRead.getMember(), boardRead.getTeam());

if (existingBoardReads.size() > 1) {
// 첫 번째 엔티티를 제외하고 나머지 삭제
List<BoardRead> 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);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class DAUScheduleUseCase {
/*
DAU 정보 : 일일 모임 생성 수, 일일 신규 가입자 수, 일일 반복 미션 생성 수, 일일 한번 미션 생성 수
*/
@Scheduled(cron = "0 59 23 * * *")
@Scheduled(cron = "0 55 23 * * *")
public void DailyTeamCreationInfoAlarm() {
Map<String, Long> todayStats = new LinkedHashMap<>();
Map<String, Long> yesterdayStats = new LinkedHashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<TeamMember, Long>, TeamMemberCustomRepository{
Optional<TeamMember> findTeamMemberByTeamAndMember(Team team, Member member);

@Lock(LockModeType.PESSIMISTIC_WRITE)
Optional<TeamMember> findTeamMemberByTeamAndMember(Team team, Member member);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
public class TeamMemberSaveService {
private final TeamMemberRepository teamMemberRepository;
public void addTeamMember(Team team, Member member) {
Optional<TeamMember> teamMember = teamMemberRepository.findTeamMemberByTeamAndMember(team, member);

checkDeletion(team);

if (teamMember.isPresent()) {
handleExistingMember(teamMember.get());
} else {
addNewTeamMember(team, member);
synchronized (this) {
Optional<TeamMember> teamMember = teamMemberRepository.findTeamMemberByTeamAndMember(team, member);
checkDeletion(team);
if (teamMember.isPresent()) {
handleExistingMember(teamMember.get());
} else {
addNewTeamMember(team, member);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 93c4f16

Please sign in to comment.