Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
0aee0d0
Feat : V1_Test1 (DB 락 X)
tmdals1207 May 2, 2025
c9cf182
Refactor : unused import 정리
tmdals1207 May 2, 2025
e8e7c00
Feat : V1_Test2(Pessimistic Lock)
tmdals1207 May 2, 2025
83a041c
Feat : V1_Test2(Pessimistic Lock)
tmdals1207 May 2, 2025
10bf5f4
Feat : V1_Test2(open-in-view + FetchJoin + DTO)
tmdals1207 May 4, 2025
5b44607
Feat : V1_Test3(open-in-view + FetchJoin + DTO)
tmdals1207 May 4, 2025
a603b8a
Merge remote-tracking branch 'origin/feature/v1' into feature/v1
tmdals1207 May 4, 2025
05a1b71
Refactor : 도메인 형식 표준에 맞게 변경
tmdals1207 May 6, 2025
e472bde
Feat : 서버 실행 시 init 자동실행 하도록 변경
tmdals1207 May 6, 2025
7ac2b2b
Fix : Test 부분에서 속성이 null인 부분 때문에 생기는 에러 주석 처리
tmdals1207 May 6, 2025
af66a72
Feat : V1_Test4(비관적 락 + 네이티브 쿼리 + 인덱스)
tmdals1207 May 6, 2025
3cdf118
Feat : V1_Test5(비관적 락 + 중복방지 + Projection + 네이티브 쿼리)
tmdals1207 May 8, 2025
21020d8
Feat : V1_Test6(비관적 락 + 중복방지 + In-Memory 캐시 + Sharding + 네이티브 쿼리)
tmdals1207 May 8, 2025
906cf4a
Feat : 티켓 예약 취소 로직 추가
tmdals1207 May 9, 2025
07671d8
Rename : 병합 전 폴더 표준화
tmdals1207 May 13, 2025
c91f7a5
Rename : 병합 전 폴더 표준화
tmdals1207 May 13, 2025
1d5a977
Rename : 병합 전 폴더 표준화
tmdals1207 May 13, 2025
34c1d67
Fix : 병합 오류 수정
tmdals1207 May 13, 2025
03f6cc2
Fix : 병합 오류 수정
tmdals1207 May 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

38 changes: 0 additions & 38 deletions src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
package com.quickpick.ureca.common.domain;
import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.time.LocalDateTime;
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {
@CreatedDate
@Column(length = 6, name = "created_at", updatable = false)
private LocalDateTime createdAt;
@LastModifiedDate
@Column(length = 6, name = "updated_at")
private LocalDateTime updatedAt;
}
package com.quickpick.ureca.v1.common.domain;

import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {
@CreatedDate
@Column(length = 6, name = "created_at", updatable = false)
private LocalDateTime createdAt;

@LastModifiedDate
@Column(length = 6, name = "updated_at")
private LocalDateTime updatedAt;

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.quickpick.ureca.v1.common.init;

import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;

@RestController
@RequiredArgsConstructor
@RequestMapping("/init")
public class InitController {

private final InitService initService;

@PostMapping
public String initializePost(
@RequestParam(defaultValue = "1000") int ticketCount,
@RequestParam(defaultValue = "10000") int userCount,
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startDate,
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime reserveDate
) {
return initService.initialize(ticketCount, userCount, startDate, reserveDate);
}
}
49 changes: 49 additions & 0 deletions src/main/java/com/quickpick/ureca/v1/common/init/InitService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.quickpick.ureca.v1.common.init;

import com.quickpick.ureca.v1.ticket.domain.Ticket;
import com.quickpick.ureca.v1.ticket.repository.TicketRepositoryV1;
import com.quickpick.ureca.v1.user.domain.User;
import com.quickpick.ureca.v1.user.repository.UserRepositoryV1;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;


@Service
@RequiredArgsConstructor
public class InitService {

private final TicketRepositoryV1 ticketRepository;
private final UserRepositoryV1 userRepositoryV1;

public String initialize(int ticketCount, int userCount, LocalDateTime startDate, LocalDateTime reserveDate) {
ticketRepository.deleteAll();
userRepositoryV1.deleteAll();

Ticket ticket = Ticket.builder()
.name("테스트 티켓")
.quantity(ticketCount)
.startDate(startDate != null ? startDate : LocalDateTime.now().plusDays(1))
.reserveDate(reserveDate != null ? reserveDate : LocalDateTime.now())
.build();
ticketRepository.save(ticket);

List<User> users = new ArrayList<>();
for (int i = 1; i <= userCount; i++) {
User user = User.builder()
.id("user" + i)
.password("pw" + i)
.name("User" + i)
.age("20")
.gender("M")
.build();
users.add(user);
}
userRepositoryV1.saveAll(users);

return "초기화 완료: 티켓 1개(" + ticketCount + "개 수량), 유저 " + userCount + "명 생성";
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/quickpick/ureca/v1/common/init/InitTrigger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//package com.quickpick.ureca.common.init;
//
//import lombok.RequiredArgsConstructor;
//import org.springframework.boot.context.event.ApplicationReadyEvent;
//import org.springframework.context.ApplicationListener;
//import org.springframework.context.annotation.Profile;
//import org.springframework.stereotype.Component;
//
//import java.time.LocalDateTime;
//
//@Component
//@Profile("local") // 배포환경에서는 작동 안 하도록
//@RequiredArgsConstructor
//public class InitTrigger implements ApplicationListener<ApplicationReadyEvent> {
//
// private final InitService initService;
//
// @Override
// public void onApplicationEvent(ApplicationReadyEvent event) {
// LocalDateTime reserveDate = LocalDateTime.now();
// LocalDateTime startDate = reserveDate.plusDays(1);
// // ticketCount, userCount는 필요에 따라 조정
// initService.initialize(3000, 10000, startDate, reserveDate);
// }
//
//}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.quickpick.ureca.v1.reserve.controller;

import com.quickpick.ureca.v1.reserve.service.ReserveServiceV1;
import com.quickpick.ureca.v1.user.repository.UserRepositoryV1;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/test-reserve")
@Slf4j
public class ReserveControllerV1 {

private final ReserveServiceV1 reserveServiceV1;
private final UserRepositoryV1 userRepositoryV1;

public ReserveControllerV1(ReserveServiceV1 reserveServiceV1, UserRepositoryV1 userRepositoryV1) {
this.reserveServiceV1 = reserveServiceV1;
this.userRepositoryV1 = userRepositoryV1;
}

@PostMapping("/reserve")
public ResponseEntity<String> reserve(@RequestParam Long userId, @RequestParam Long ticketId) {
try {
reserveServiceV1.reserveTicket(userId, ticketId);
return ResponseEntity.ok("예약 성공");
} catch (Exception e) {
log.error("예약 실패: {}", e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("예약 실패: " + e.getMessage());
}
}

// open-in-view + Fetch-Join + DTO
// @PostMapping
// public ResponseEntity<TicketReserveResponse> reserve(@RequestParam Long userId, @RequestParam Long ticketId) {
// try {
// Ticket ticket = reserveServiceV1.reserveTicket(userId, ticketId);
// User user = userRepository.findById(userId).orElseThrow();
// return ResponseEntity.ok(TicketReserveResponse.of(ticket, user));
// } catch (Exception e) {
// log.error("예약 실패: {}", e.getMessage());
// return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
// }
// }

@PostMapping("/cancel")
public ResponseEntity<String> cancelReservation(@RequestParam Long userId, @RequestParam Long ticketId) {
log.info("{}의 티켓 취소 요청", userId);
reserveServiceV1.cancelReservation(userId, ticketId);
return ResponseEntity.ok("예약이 성공적으로 취소되었습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.quickpick.ureca.reserve.domain;
package com.quickpick.ureca.v1.reserve.domain;

import com.quickpick.ureca.common.domain.BaseEntity;
import com.quickpick.ureca.reserve.status.ReserveStatus;
import com.quickpick.ureca.user.domain.User;
import com.quickpick.ureca.v1.common.domain.BaseEntity;
import com.quickpick.ureca.v1.reserve.status.ReserveStatusV1;
import com.quickpick.ureca.v1.user.domain.User;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -11,7 +11,7 @@
@Entity
@Getter
@NoArgsConstructor
public class Reserve extends BaseEntity {
public class ReserveV1 extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -24,5 +24,5 @@ public class Reserve extends BaseEntity {

@Enumerated(EnumType.STRING)
@Column(nullable = false)
private ReserveStatus status;
private ReserveStatusV1 status;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.quickpick.ureca.v1.reserve.dto;

import com.quickpick.ureca.v1.ticket.domain.Ticket;
import com.quickpick.ureca.v1.user.domain.User;

public record TicketReserveResponseV1(
Long ticketId,
String ticketName,
int remainingQuantity,
String reservedByUsername
) {
public static TicketReserveResponseV1 of(Ticket ticket, User user) {
return new TicketReserveResponseV1(
ticket.getTicketId(),
ticket.getName(),
ticket.getQuantity(),
user.getId()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.quickpick.ureca.v1.reserve.repository;

import com.quickpick.ureca.v1.reserve.domain.ReserveV1;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ReserveRepositoryV1 extends JpaRepository<ReserveV1, Long> {
}
Loading
Loading