Fix: 트랜잭션 처리
This commit is contained in:
parent
b94420a91f
commit
8649ae0a67
@ -11,7 +11,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Isolation;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@ -30,19 +29,18 @@ public class ImageAsyncService {
|
||||
|
||||
@Async("imageUploadExecutor")
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public CompletableFuture<Void> asyncImageUpload(final List<MultipartFile> imageFileList, final Folder folder, final Integer projectId) {
|
||||
public CompletableFuture<Void> asyncImageUpload(final List<MultipartFile> imageFileList, final Folder folder, final Integer projectId) {
|
||||
log.debug("현재 스레드 - {} 업로드 파일 개수 - {}, 현재 작업 큐 용량 - {}",
|
||||
Thread.currentThread().getName(),
|
||||
imageFileList.size(),
|
||||
imageUploadExecutor.getThreadPoolExecutor().getQueue().size()); // 큐에 쌓인 작업 수 출력);
|
||||
imageUploadExecutor.getThreadPoolExecutor().getQueue().size()
|
||||
); // 큐에 쌓인 작업 수 출력);
|
||||
|
||||
imageFileList.forEach(file -> {
|
||||
try{
|
||||
String extension = getExtension(file.getOriginalFilename());
|
||||
String imageKey = s3UploadService.uploadImageFile(file, extension, projectId);
|
||||
|
||||
try {
|
||||
String imageKey = imageUpload(projectId, file);
|
||||
createImage(file, imageKey, folder);
|
||||
}catch (Exception e){
|
||||
} catch (Exception e) {
|
||||
log.error("이미지 업로드 실패: {}", file.getOriginalFilename(), e);
|
||||
throw new CustomException(ErrorCode.FAIL_TO_CREATE_FILE);
|
||||
}
|
||||
@ -52,15 +50,19 @@ public class ImageAsyncService {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW,isolation = Isolation.READ_COMMITTED)
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
public String imageUpload(Integer projectId, MultipartFile file) {
|
||||
String extension = getExtension(file.getOriginalFilename());
|
||||
return s3UploadService.uploadImageFile(file, extension, projectId);
|
||||
}
|
||||
|
||||
public void createImage(MultipartFile file, String imageKey, Folder folder) {
|
||||
try {
|
||||
String name = file.getOriginalFilename();
|
||||
String extension = getExtension(name);
|
||||
log.debug("image 파일 {} {} {} {}", name, extension, imageKey, folder.getId());
|
||||
Image image = Image.of(name, imageKey, extension, folder);
|
||||
imageRepository.save(image);
|
||||
}catch (Exception e){
|
||||
} catch (Exception e) {
|
||||
log.debug("이미지 DB 저장 실패: ", e);
|
||||
s3UploadService.deleteImageFromS3(imageKey);
|
||||
throw new CustomException(ErrorCode.FAIL_TO_CREATE_FILE);
|
||||
|
@ -40,7 +40,6 @@ import java.util.stream.Stream;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@Transactional
|
||||
@RequiredArgsConstructor
|
||||
public class ImageService {
|
||||
|
||||
@ -56,9 +55,8 @@ public class ImageService {
|
||||
@CheckPrivilege(value = PrivilegeType.EDITOR)
|
||||
public void uploadImageList(final List<MultipartFile> imageList, final Integer folderId, final Integer projectId) {
|
||||
Folder folder = getOrCreateFolder(folderId, projectId);
|
||||
folderRepository.flush();
|
||||
|
||||
log.debug("folder Id {}, Project Id {}",folder.getId(), folder.getProject().getId());
|
||||
log.debug("folder Id {}, Project Id {}", folder.getId(), folder.getProject().getId());
|
||||
long prev = System.currentTimeMillis();
|
||||
|
||||
// 동적 배치 크기 계산
|
||||
@ -78,7 +76,6 @@ public class ImageService {
|
||||
List<MultipartFile> batch = imageList.subList(i, Math.min(i + batchSize, imageList.size()));
|
||||
|
||||
CompletableFuture<Void> future = imageAsyncService.asyncImageUpload(batch, folder, projectId);
|
||||
// 모든 비동기 작업이 완료될 때까지 기다림
|
||||
futures.add(future);
|
||||
}
|
||||
|
||||
@ -308,7 +305,8 @@ public class ImageService {
|
||||
String currentDateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
Project project = getProject(projectId);
|
||||
Folder folder = Folder.of(currentDateTime, null, project);
|
||||
folderRepository.save(folder); // 새로운 폴더를 저장
|
||||
folderRepository.saveAndFlush(folder); // 새로운 폴더를 저장
|
||||
|
||||
return folder;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.worlabel.domain.project.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.worlabel.domain.folder.entity.Folder;
|
||||
import com.worlabel.domain.labelcategory.entity.ProjectCategory;
|
||||
import com.worlabel.domain.model.entity.AiModel;
|
||||
import com.worlabel.domain.workspace.entity.Workspace;
|
||||
@ -54,6 +55,12 @@ public class Project extends BaseEntity {
|
||||
@OneToMany(mappedBy = "project", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
private List<ProjectCategory> categoryList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 프로젝트에 속한 폴더
|
||||
*/
|
||||
@OneToMany(mappedBy = "project", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
private List<Folder> folderList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 프로젝트에 속한 모델
|
||||
*/
|
||||
@ -74,4 +81,8 @@ public class Project extends BaseEntity {
|
||||
this.title = title;
|
||||
this.projectType = projectType;
|
||||
}
|
||||
|
||||
public void createFolder(final Folder folder) {
|
||||
folderList.add(folder);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user