diff --git a/backend/frazzle/.gitignore b/backend/frazzle/.gitignore index f95374a..710927d 100644 --- a/backend/frazzle/.gitignore +++ b/backend/frazzle/.gitignore @@ -37,4 +37,4 @@ out/ ### VS Code ### .vscode/ -application-*.properties \ No newline at end of file +application-*.yml \ No newline at end of file diff --git a/backend/frazzle/src/main/java/com/frazzle/main/domain/piece/entity/Piece.java b/backend/frazzle/src/main/java/com/frazzle/main/domain/piece/entity/Piece.java index b77aa9b..236b101 100644 --- a/backend/frazzle/src/main/java/com/frazzle/main/domain/piece/entity/Piece.java +++ b/backend/frazzle/src/main/java/com/frazzle/main/domain/piece/entity/Piece.java @@ -30,6 +30,10 @@ public class Piece { @JoinColumn(name = "user_id") private User user; + @Version + @Column(name = "version") + private Integer version; + @UpdateTimestamp @Column(name = "modified_at", columnDefinition = "TIMESTAMP") private LocalDateTime modifiedAt; diff --git a/backend/frazzle/src/main/java/com/frazzle/main/global/exception/ErrorCode.java b/backend/frazzle/src/main/java/com/frazzle/main/global/exception/ErrorCode.java index 05cdaa4..0c44592 100644 --- a/backend/frazzle/src/main/java/com/frazzle/main/global/exception/ErrorCode.java +++ b/backend/frazzle/src/main/java/com/frazzle/main/global/exception/ErrorCode.java @@ -35,7 +35,8 @@ public enum ErrorCode { IMAGE_NOT_FOUND("이미지가 존재하지 않습니다.", HttpStatus.NOT_FOUND), VOTE_NOT_FOUND("투표가 비활성화 되었습니다.", HttpStatus.NOT_FOUND), NOTIFICATION_NOT_FOUND("존재하지 않는 초대 요청입니다.", HttpStatus.NOT_FOUND), - NOT_COMPLETE_GAME("게임을 클리어하지 않았습니다.", HttpStatus.NOT_FOUND) + NOT_COMPLETE_GAME("게임을 클리어하지 않았습니다.", HttpStatus.NOT_FOUND), + CONCURRENT_UPDATE_PIECE("다른 사용자가 먼저 퍼즐 조각을 업로드하였습니다.", HttpStatus.CONFLICT) ; private final String message; diff --git a/backend/frazzle/src/main/java/com/frazzle/main/global/exception/GlobalExceptionHandler.java b/backend/frazzle/src/main/java/com/frazzle/main/global/exception/GlobalExceptionHandler.java index b84a662..828919b 100644 --- a/backend/frazzle/src/main/java/com/frazzle/main/global/exception/GlobalExceptionHandler.java +++ b/backend/frazzle/src/main/java/com/frazzle/main/global/exception/GlobalExceptionHandler.java @@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.orm.ObjectOptimisticLockingFailureException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -25,6 +26,18 @@ public ResponseEntity> handleCustomException(CustomException e return new ResponseEntity<>(response, ex.getErrorCode().getHttpStatus()); } + @ExceptionHandler(ObjectOptimisticLockingFailureException.class) + public ResponseEntity> handleOptimisticLockingException(Exception ex) { + logger.error("[OptimisticException] message: " + ex.getMessage()); + + ResultDto response = ResultDto.res( + ErrorCode.CONCURRENT_UPDATE_PIECE.getHttpStatus().value(), + ErrorCode.CONCURRENT_UPDATE_PIECE.getMessage() + ); + + return new ResponseEntity<>(response, HttpStatus.CONFLICT); + } + @ExceptionHandler(RuntimeException.class) public ResponseEntity> handleRuntimeException(RuntimeException ex) { logger.error("[RuntimeException] message: " + ex.getMessage()); diff --git a/backend/frazzle/src/main/resources/application.properties b/backend/frazzle/src/main/resources/application.properties deleted file mode 100644 index 7365a38..0000000 --- a/backend/frazzle/src/main/resources/application.properties +++ /dev/null @@ -1,25 +0,0 @@ -spring.application.name=frazzle -server.servlet.context-path=/api/v1 -springdoc.api-docs.path=/v3/api-docs -springdoc.swagger-ui.path=/swagger-ui.html - -# JPA -spring.jpa.hibernate.ddl-auto=update -spring.jpa.show-sql=true -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect -spring.jpa.properties.hibernate.format_sql=true -spring.jpa.properties.hibernate.jdbc.batch_size=20 - -# HikariCP -spring.datasource.hikari.connection-timeout=30000 -spring.datasource.hikari.maximum-pool-size=10 -spring.datasource.hikari.minimum-idle=5 -spring.datasource.hikari.idle-timeout=600000 -spring.datasource.hikari.max-lifetime=1800000 - -#My SQL, #oauth -spring.profiles.include=develop,oauth - -spring.servlet.multipart.enabled=true -spring.servlet.multipart.max-file-size=10MB -spring.servlet.multipart.max-request-size=10MB \ No newline at end of file diff --git a/backend/frazzle/src/main/resources/application.yml b/backend/frazzle/src/main/resources/application.yml new file mode 100644 index 0000000..35c0d8d --- /dev/null +++ b/backend/frazzle/src/main/resources/application.yml @@ -0,0 +1,38 @@ +spring: + application: + name: frazzle + + servlet: + context-path: /api/v1 + multipart: + enabled: true + max-file-size: 10MB + max-request-size: 10MB + + profiles: + include: secret + + jpa: + hibernate: + ddl-auto: update + show-sql: true + properties: + hibernate: + dialect: org.hibernate.dialect.MySQL8Dialect + format_sql: true + jdbc: + batch_size: 20 + + datasource: + hikari: + connection-timeout: 30000 + maximum-pool-size: 10 + minimum-idle: 5 + idle-timeout: 600000 + max-lifetime: 1800000 + +springdoc: + api-docs: + path: /v3/api-docs + swagger-ui: + path: /swagger-ui.html