[Java] CS 스터디 10주차
@Transactional 은 어떤 기능을 하나요?
- 트랜잭션 경계 설정
- 메서드나 클래스에
@Transactional
을 붙이면 해당 범위가 하나의 트랜잭션으로 처리됩니다.
- 메서드나 클래스에
- 선언적 트랜잭션 관리
- 코드 내에 직접 트랜잭션 관련 로직을 작성하지 않고도 어노테이션만으로 트랜잭션을 관리할 수 있습니다.
- 자동 커밋과 롤백
- 트랜잭션이 성공적으로 완료되면 자동으로 커밋되고, 예외 발생 시 자동으로 롤백됩니다.
- 전파 속성 설정
- 전파 속성이란 이미 트랜잭션이 진행 중일 때, 추가 트랜잭션 진행을 어떻게 결정하는 것을 말합니다.
propagation
속성을 통해 트랜잭션의 전파 방식을 지정할 수 있습니다.- 예를 들어
REQUIRED
,REQUIRES_NEW
등의 옵션이 있습니다.
- 격리 수준 설정
isolation
속성으로 트랜잭션의 격리 수준을 설정할 수 있습니다.
- 타임아웃 설정
timeout
속성으로 트랜잭션 실행 시간 제한을 설정할 수 있습니다.
- 읽기 전용 트랜잭션
readOnly
속성을 통해 읽기 전용 트랜잭션을 설정할 수 있습니다.
- 특정 예외에 대한 롤백 설정
rollbackFor
속성으로 특정 예외 발생 시 롤백하도록 설정할 수 있습니다.
@Transactional(readonly=true) 는 어떤 기능인가요? 이게 도움이 되나요?
@Transactional(readOnly=true)
는 스프링에서 제공하는 트랜잭션 관리 기능 중 하나로, 주로 읽기 전용 작업에 사용됩니다. 그리고 이와 같은 장점이 있습니다.
- 성능 최적화
- 영속성 컨텍스트의 변경 감지(Dirty Checking) 기능을 비활성화하여 메모리 사용량을 줄입니다.
- 데이터베이스의 쿼리 최적화가 가능해집니다.
- 데이터 무결성 보장
- 실수로 데이터를 수정하는 것을 방지하여 데이터의 일관성을 유지합니다.
- 가독성 향상
- 해당 메서드가 읽기 전용 작업임을 명확히 표시하여 코드의 의도를 더 잘 전달합니다.
- 데이터베이스 최적화
- 일부 데이터베이스에서는 읽기 전용 트랜잭션에 대해 특별한 최적화를 수행할 수 있습니다.
그런데, 읽기에 트랜잭션을 걸 필요가 있나요? @Transactional을 안 붙이면 되는거 아닐까요?
읽기 작업에 readOnly = true
를 사용하는 것에는 몇 가지 이점이 있습니다.
- 성능 최적화
- 영속성 컨텍스트의 변경 감지(Dirty Checking) 기능을 비활성화하여 메모리 사용량을 줄입니다.
- 일부 데이터베이스에서는 읽기 전용 트랜잭션에 대해 특별한 최적화를 수행할 수 있습니다.
- 데이터 일관성
- 트랜잭션 내에서 일관된 데이터 스냅샷을 제공하여 데이터 일관성을 보장합니다.
- 의도 명확화
- 해당 메서드가 읽기 전용 작업임을 명확히 표시하여 코드의 의도를 더 잘 전달합니다.
Java 에서 Annotation 은 어떤 기능을 하나요?
- 컴파일러에게 정보 제공
- 컴파일러에게 코드 작성 문법 오류를 체크하도록 정보를 제공합니다.
- 예를 들어
@Override
어노테이션은 메서드가 오버라이드되었음을 컴파일러에게 알려줍니다.
- 런타임 처리
- 실행 시에 특정 기능을 실행하도록 정보를 제공합니다.
- 리플렉션을 통해 런타임에 어노테이션 정보를 읽어 처리할 수 있습니다.
- 메타데이터 제공
- 코드에 대한 메타데이터를 제공합니다.
- 메타데이터: 애플리케이션이 처리해야 할 데이터가 아니라, 컴파일 과정과 실행 과정에서 코드를 어떻게 컴파일하고 처리할 것인지 알려주는 정보
- 코드에 대한 메타데이터를 제공합니다.
- AOP(관점 지향 프로그래밍) 지원
- 비즈니스 로직과 시스템 설정을 분리하여 관심사를 분리할 수 있게 해줍니다.
- 코드 가독성 및 유지보수성 향상
- 코드의 의도를 명확히 하고 구조화하는데 도움을 줍니다.
- 사용자 정의 기능
- 개발자가 직접 커스텀 어노테이션을 정의하여 원하는 용도로 활용할 수 있습니다.
별 기능이 없는 것 같은데, 어떻게 Spring 에서는 Annotation 이 그렇게 많은 기능을 하는 걸까요?
- 리플렉션(Reflection) 활용
- Spring은 Java의 리플렉션 기능을 적극적으로 활용합니다.
- 리플렉션을 통해 런타임에 클래스, 메서드, 필드 등의 메타데이터를 분석하고 조작할 수 있습니다.
- AOP(Aspect-Oriented Programming) 지원
- Spring은 AOP를 통해 어노테이션이 적용된 코드 주변에 추가적인 동작을 삽입할 수 있습니다.
- 이를 통해 트랜잭션 관리, 보안 등의 기능을 구현합니다.
- IoC(Inversion of Control) 컨테이너
- Spring의 IoC 컨테이너는 어노테이션을 해석하여 Bean을 생성하고 관리합니다.
- 예를 들어
@Autowired
어노테이션은 의존성 주입을 자동화합니다.
- Spring의 IoC 컨테이너는 어노테이션을 해석하여 Bean을 생성하고 관리합니다.
- 예를 들어
- 컴포넌트 스캔
@ComponentScan
어노테이션을 통해 Spring은 특정 패키지 내의 컴포넌트들을 자동으로 검색하고 등록합니다.
- 설정 자동화
@EnableAutoConfiguration
어노테이션은 클래스패스 설정, 다른 빈, 다양한 프로퍼티 설정에 기반하여 자동으로 빈들을 등록합니다.
- 메타 어노테이션
- Spring은 어노테이션 위에 다른 어노테이션을 정의하는 메타 어노테이션을 지원합니다.
- 이를 통해 복잡한 설정을 단순화할 수 있습니다.
- 어노테이션 프로세서
- Spring은 컴파일 시점에 어노테이션을 처리하는 어노테이션 프로세서(ex. Lombok)를 사용하여 추가적인 소스 코드나 리소스 파일을 생성할 수 있습니다.
- 프레임워크 통합
- Spring은 JPA, Spring Security 등 다양한 프레임워크와 통합되어 있어, 이들 프레임워크의 기능을 어노테이션을 통해 쉽게 활용할 수 있습니다.
Lombok의 @Data를 잘 사용하지 않는 이유는 무엇일까요?
- 과도한 기능 생성
@Data
는 너무 많은 기능을 한 번에 생성합니다.getter
,setter
,toString()
,equals()
,hashCode()
등 모든 메서드를 자동으로 만들어내어 의도치 않은 코드를 만들어낼 수 있습니다.
- 성능 및 안전성 문제
- 특히 JPA 엔티티에서
@Data
사용 시 양방향 관계에서StackOverflow
에러가 발생할 수 있습니다. toString()
이나equals()
,hashCode()
메서드가 무한 재귀에 빠질 위험이 있습니다.
- 특히 JPA 엔티티에서
- 코드 가독성 저하
@Data
가 생성하는 모든 메서드를 명시적으로 볼 수 없어 코드의 의도를 파악하기 어려울 수 있습니다.
- 불변성 침해
- 모든 필드에 대해
setter
를 생성하므로, 객체의 불변성을 유지하기 어려워집니다. - 세밀한 제어 부족
- 특정 필드만 포함하거나 제외하는 등의 세밀한 제어가 어렵습니다.
- 개별 어노테이션(
@Getter
,@Setter
등)을 사용하는 것이 더 명확하고 제어가 용이합니다.
- 디버깅 어려움 - 자동 생성된 코드로 인해 디버깅이 어려워질 수 있습니다.
Tomcat이 정확히 어떤 역할을 하는 도구인가요?
Tomcat은 Java 기반의 웹 애플리케이션 서버입니다.
- 서블릿 컨테이너
- Tomcat의 가장 중요한 역할은 Java 서블릿을 실행하는 컨테이너 기능입니다.
- 서블릿: 클라이언트의 요청을 처리하고 동적인 웹 콘텐츠를 생성하는 Java 프로그램
- Tomcat은 이러한 서블릿을 관리하고 실행하여 동적인 웹 애플리케이션을 제공합니다.
- Tomcat의 가장 중요한 역할은 Java 서블릿을 실행하는 컨테이너 기능입니다.
- JSP 엔진
- Tomcat은 JavaServer Pages(JSP)를 처리하는 엔진 역할도 수행합니다.
- JSP: HTML 내에 Java 코드를 포함하여 동적인 웹 페이지를 생성하는 기술
- Tomcat은 JSP 페이지를 컴파일하고 실행하여 HTML로 변환한 후 클라이언트에게 제공합니다.
- Tomcat은 JavaServer Pages(JSP)를 처리하는 엔진 역할도 수행합니다.
- 웹 서버 기능
- Tomcat은 기본적인 웹 서버 기능도 제공합니다.
- HTML, CSS, JavaScript 등의 정적 파일을 클라이언트에게 제공할 수 있습니다.
- 하지만 주로 동적 콘텐츠 처리에 특화되어 있습니다.
- 애플리케이션 서버
- Tomcat은 Java 웹 애플리케이션을 실행하고 관리하는 애플리케이션 서버 역할을 합니다.
- 개발자들이 작성한 Java 웹 애플리케이션을 배포하고 실행할 수 있는 환경을 제공합니다.
- 확장성 제공
- Tomcat은 다양한 설정 옵션과 확장 가능한 구조를 제공하여 사용자의 요구에 맞게 커스터마이징할 수 있습니다.
- 이를 통해 성능 튜닝, 보안 설정, 추가 기능 구현 등이 가능합니다.
혹시 Netty에 대해 들어보셨나요? 왜 이런 것을 사용할까요?
Netty는 비동기 이벤트 기반 네트워크 애플리케이션 프레임워크입니다. 고성능, 고확장성 네트워크 애플리케이션을 개발할 때 자주 사용됩니다.
- 높은 성능과 확장성
- 비동기 및 이벤트 기반 아키텍처를 사용하여 적은 수의 스레드로 많은 동시 연결을 처리할 수 있습니다.
- Non-Blocking I/O를 사용하여 리소스를 효율적으로 활용합니다.
- 개발 편의성
- 복잡한 네트워크 프로그래밍을 추상화하여 개발자가 비즈니스 로직에 집중할 수 있게 합니다.
- 다양한 프로토콜(HTTP, WebSocket 등)을 기본적으로 지원합니다.
- 유연성과 확장성
- 모듈식 아키텍처를 통해 필요한 기능만 선택적으로 사용할 수 있습니다.
- 사용자 정의 프로토콜 및 코덱을 쉽게 구현할 수 있습니다.
- 안정성과 성숙도
- 많은 대규모 기업(예: 라인, 카카오, 트위터)에서 사용되어 검증되었습니다.
- 지속적인 업데이트와 커뮤니티 지원을 받고 있습니다.
동기(Synchronous)와 비동기(Asynchronous)
동기와 비동기는 작업의 완료 시점과 결과 처리에 관한 개념입니다.
- 동기(Synchronous)
- 작업의 결과를 바로 받아 처리합니다.
- 작업의 순서와 완료 여부에 관심이 있습니다.
- 한 작업이 끝나야 다음 작업을 진행합니다.
- 비동기(Asynchronous)
- 작업의 결과를 나중에 받아 처리합니다(주로 콜백 함수 사용).
- 작업의 순서와 완료 여부에 크게 관심을 두지 않습니다.
- 여러 작업을 동시에 진행할 수 있습니다.
Blocking과 Non-blocking
Blocking과 Non-blocking은 제어권에 관한 개념입니다.
- Blocking
- 작업을 요청한 후 그 작업이 완료될 때까지 대기합니다.
- 제어권을 작업을 수행하는 함수가 가집니다.
- Non-blocking
- 작업을 요청한 후 즉시 다음 작업을 수행합니다.
- 제어권을 작업을 요청한 함수가 계속 가지고 있습니다.
주요 차이점
- 관심사
- 동기/비동기는 작업 완료와 결과에, Blocking/Non-blocking은 제어권에 초점을 맞춥니다.
- 조합 가능성
- 동기/비동기와 Blocking/Non-blocking은 서로 조합될 수 있습니다.
- 예를 들어, 동기-Non-blocking이나 비동기-Blocking 같은 조합이 가능합니다.
- 구현 방식
- 비동기는 주로 콜백, Promise, async/await 등으로 구현되며
- Non-blocking은 주로 이벤트 루프나 폴링 방식으로 구현됩니다.
Leave a comment