목록분류 전체보기 (96)
신비한 개발사전
문제 의식데이터 수정 작업을 수행할 때, 한 트랜잭션 단위 안에서 작업이 이루어지도록 메서드에 @Transactional 애노테이션을 붙인다. 중간에 문제가 발생한 경우 아예 작업 자체가 실행되지 않았던 것처럼 롤백을 해야 하기 때문이다. 여기에서 추가로 고려해볼 점은, @Transactional을 사용한다고 해서 동시성을 지킬 수 있는 것은 아니라는 것이다. 한 DB 칼럼의 값을 변경하려고 할 때, 엔티티를 조회해온 후 내부 값을 변경하고 다시 영속화하는 흐름을 따른다고 가정하자.@Servicepublic class ItemService { private final ItemRepository itemRepository; public ItemService(ItemRepository itemRe..
온라인에서 YAML 파일에 대한 리소스를 찾을 때 .yml 확장자와 .yaml 확장자 둘 다 심심찮게 볼 수 있다. 처음엔 아예 다른 확장자인 줄 알았는데, 사실 둘 다 YAML을 지원하는 확장자이고 기술적으로 차이가 전혀 없다. 과거 MS-DOS와 Windows 95, Windows NT 3.5 이하 버전의 시스템에서는 파일명에 글자수 제한이 있었다. 이때 확장자는 최대 3자까지만 허용됐었고, YAML이 나왔을 당시에 모던 시스템에서는 해당 제한이 없어졌지만 옛날 시스템과의 호환성을 위해 .yml 확장자를 선택하는(혹은 선택해야만 하는) 경우가 많았다고 한다. (신기한 건 JSON도 같은 시대에 나왔는데 .json은 줄여쓰지 않은 듯하다.. 🤔) .htm과 .html 파일도 동일한 이유로 HTML의 ..

지난 Spring REST Docs 적용기에서 만들어 본 API 문서를 EC2 서버에 배포해봤다. build.gradle 파일에 아래처럼 asciidoctor가 생성한 문서를 "static/docs" 경로로 이동시키는 명령어를 추가했다. 프로젝트의 resources/static 패키지에 들어있는 다른 파일들처럼 API 문서도 정적으로 호스팅되길 기대하면서..bootJar { dependsOn asciidoctor from ("${asciidoctor.outputDir}") { into('static/docs') }} 하지만 호스팅되어 있어야 할 URL 주소는 내 문서를 띄워주지 않았다. 문서 파일이 생성된 후에 resources/static/docs 디렉토리로 이동시켰음에도 ..

Spring REST Docs는 API 문서를 작성할 때 필요한 각종 코드 스니펫을 자동으로 생성해주는 도구다. 생성된 스니펫을 조합해 자유도 높은 형식으로 API 문서를 만들어낼 수 있다. 순수한 문서이기 때문에 Swagger처럼 API 호출을 시뮬레이팅할 순 없지만, 테스트 코드를 기반으로 문서화를 지원하기 때문에 겸사겸사 테스트 코드를 작성하는 기회를 마련해주기도 한다. Spring REST Docs는 AsciiDoc과 Mustache 문법을 사용한다. 초기 세팅build.gradle에 REST Docs 관련 설정을 먼저 추가해준다. REST Docs가 생성해주는 스니펫을 어디에 저장할지, 그리고 빌드할 때 어디에 있는 asciidoc으로 최종 HTML 문서를 만들지 등을 설정한다.plugins {..

echo명령어 다음에 입력하는 내용을 그대로 반환하는 것이 기본 동작이다. 파일에 컨텐츠를 넣을 때에도 echo를 사용할 수 있다.echo ${컨텐츠} > ${파일}명시한 파일의 내용을 컨텐츠로 채운다. 해당 파일에 이미 컨텐츠가 있었을 경우, 모두 새 내용으로 덮어쓰기 된다.echo ${컨텐츠} >> ${파일}기존 컨텐츠는 두고 새 줄에 내용을 덧붙인다.⚠ 만약 echo를 사용해 #!/bin/sh 실행 명령어를 스크립트 파일에 추가하려고 할 경우 큰 따옴표(")가 아닌 작은 따옴표(')를 써야 한다. 큰 따옴표를 쓸 경우 바로 /bin/sh를 실행시켜버린다.echo '#!/bin/sh' > deploy.shShell scripting 언어에서 큰 따옴표는 특수문자를 해석할 여지를 준다. 반대로 작은 따..

아무런 문제 없던 코드를 리팩터링하는 도중에 갑자기 "For queries with named parameters you need to provide names for method parameters" 오류가 발생하기 시작했다.. 아래는 오류가 발생한 코드다. 해당 코드는 잘 동작함을 확인했었고 이후엔 수정한 적도 없는데, 다른 변동사항을 확인하기 위해 테스트를 돌려보니 동작하지 않는다. 어디가 잘못되었길래 없던 오류가 나타났을까?@Query(""" SELECT t FROM Theme t JOIN Reservation r ON r.details.theme = t WHERE r.details.date >= :from AND r.details.date findTopThe..
JPA를 사용해보면서 엔티티라는 개념에 익숙해질 때쯤, "DB에 의존적인 설계"라는 표현을 접하게 됐다.@Entityclass User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private int age; private String street; private String city; private int zip;} 생각해보니 예시의 User 엔티티는 데이터베이스 테이블의 칼럼과 정확히 일치하도록 필드를 둔 것이고, 따라서 DB에 의존한다는 말이 나온 것이다. JPA가 없는 상황에서 동일한 정보로 User 객체를 만들어야 했다면, 아..
트랜잭션은 작은 작업들을 한 작업처럼 몰아서 처리하는 하나의 실행 단위다. 함께 처리해야 하는 작업들 중 하나라도 문제가 생겼을 때, 일부 성공한 작업들도 처음부터 수행되지 않은 것처럼 롤백(rollback)을 하기 위해서는 트랜잭션으로 실행되어야 한다. Spring 애플리케이션에서는 @Transactional 애노테이션을 통해 메서드가 트랜잭션 단위로 실행되도록 제어할 수 있다.트랜잭션이 필요한 대표적인 예시로는 DB의 데이터 변경 로직과 다른 비즈니스 로직이 섞여있는 경우가 있다. 아래 예시에서는 @Transactional이 없으면 문제가 발생할 수 있다.@Servicepublic class ReservationService { private final ReservationRepository r..