![article thumbnail](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fni3M5%2Fbtso082mGHz%2FVVecI21YFuOpGS3NQ5XarK%2Fimg.png)
스프링이 제공하는 트랜잭션 전파에 대해서 알아보자. 외부 트랜잭션이 수행중인데, 내부 트랜잭션이 추가로 수행됨 외부 트랜잭션이 수행중이고, 아직 끝나지 않았는데, 내부 트랜잭션이 수행된다. 외부 트랜잭션이라고 이름 붙인 것은 둘 중 상대적으로 밖에 있기 때문에 외부 트랜잭션이라 한다. 처음 시작된 트랜잭션으로 이해하면 된다. 내부 트랜잭션은 외부에 트랜잭션이 수행되고 있는 도중에 호출되기 때문에 마치 내부에 있는것 처럼 보여서 내부 트랜잭션이라 한다. 스프링 이 경우 외부 트랜잭션과 내부 트랜잭션을 묶어서 하나의 트랜잭션을 만들어준다. 내부 트랜잭션이 외부 트랜잭션에 참여하는 것이다. 이것이 기본 동작이고, 옵션을 통해 다른 동작방식도 선택할 수 있다. 스프링은 이해를 돕기 위해 논리 트랜잭션과 물리 트..
![article thumbnail](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdA1489%2FbtsoyXUhxJx%2FjHOVRpYmhyaRrkZTuT7dTk%2Fimg.png)
@Slf4j @SpringBootTest public class BasicTxTest { @Autowired PlatformTransactionManager txManager; @TestConfiguration static class Config{ @Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } } @Test void commit(){ log.info("트랜잭션 시작"); TransactionStatus status = txManager.getTransaction(new DefaultTransactionAt..
Getter Setter를 사용하는 이유 객체의 무결성을 보장하기 위해 예를 들어, 만약 외부에서 몸무게라는 필드에 직접 접근한다면 0보다 낮은 값을 줄 수도 있다. 이 경우 객체의 무결성이 깨지기 때문에 이를 방지하기 위해 Getter/Setter를 사용하여 데이터의 무결성을 지켜준다. 🤔 무결성이란 무엇인가? 데이터의 정확성과 일관성을 유지하고 보증하는 것을 말한다. 🤔 Getter/Setter를 사용하면 데이터 무결성이 지켜지는가? Getter, Setter를 이용해서 데이터를 생성 및 접근을 하게 되면 들어오는 값을 바로 저장하는 게 아닌, 한번 검증하고 처리할 수 있도록 할 수 있기 때문에 데이터의 무결성이 지켜진다. Getter : 본 필드의 값을 숨긴 채 내부에서 가공된 값을 꺼낼 수 있다...
![article thumbnail](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6ahu1%2FbtsnIJP6gkB%2FeZP9oT5ckiydDaxDknq4sK%2Fimg.png)
@Transactional 을 사용하면 스프링의 트랜잭션 AOP가 적용된다. 트랜잭션 AOP는 기본적으로 프록시 방식의 AOP를 사용한다. 앞서 배운 것 처럼 @Transactional 을 적용하면 프록시 객체가 요청을 먼저 받아서 트랜잭션을 처리하고, 실제 객체를 호출해준다. 따라서 트랜잭션을 적용하려면 항상 프록시를 통해서 대상 객체(Target)을 호출해야 한다. 이렇게 해야 프록시에서 먼저 트랜잭션을 적용하고, 이후에 대상 객체를 호출하게 된다. 만약 프록시를 거치지 않고 대상 객체를 직접 호출하게 되면 AOP가 적용되지 않고, 트랜잭션도 적용되지 않는다. AOP를 적용하면 스프링은 대상 객체 대신에 프록시를 스프링 빈으로 등록한다. 따라서 스프링은 의존관계 주입시에 항상 실제 객체 대신에 프록시..
![article thumbnail](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcV4lfH%2FbtsnnNjtu9r%2FNW27eslcWWuqTt3SBrMuY1%2Fimg.png)
JPA(Java Persistence API) Java 진영에서 ORM(Object-Relational Mapping) 기술 표준으로 사용하는 인터페이스 모음 자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스 인터페이스 이기 때문에 Hibernate, OpenJPA 등이 JPA를 구현함 왜 JPA를 사용해야 할까? JPA는 반복적인 CRUD SQL을 처리해준다. JPA는 매핑된 관계를 이용해서 SQL을 생성하고 실행하는데, 개발자는 어떤 SQL이 실행될지 생각만하면 되고, 예측도 쉽게 할 수 있다. 추가적으로 JPA는 네이티브 SQL이란 기능을 제공해주는데 관계 매핑이 어렵거나 성능에 대한 이슈가 우려되는 경우 SQL을 직접 작성하여 사용할 수 있다. JPA를 사용하여 얻을 수..
@Test 본 어노테이션을 붙이면 Test 메서드로 인식하고 테스트 한다. JUnit5 기준으로 접근제한자가 Default 여도 된다. (JUnit4 까지는 public이어야 했었다.) @Test void create1() { Study study = new Study(); assertNotNull(study); System.out.println("create1()"); } @Test void create2() { System.out.println("create2()"); } @BeforeAll 본 어노테이션을 붙인 메서드는 해당 테스트 클래스를 초기화할 때 딱 한번 수행되는 메서드다. 메서드 시그니쳐는 static 으로 선언해야한다. @BeforeAll static void beforeAll() { S..
![article thumbnail](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6v9wh%2Fbtsm4CXTmX8%2FMzygnmgoji0bukW7YtzS10%2Fimg.png)
JDBC JDBC란 DB에 접근(Connectivity)할 수 있도록 Java에서 제공하는 API이다. JDBC API가 있고 JDBC DriverManager가 DB제품에 따른 드라이버를 생성하여 JDBC API에 맞게 동작할 수 있게 처리해준다. 따라서 우리는 JDBC API 변경없이 JDBC 드라이버만 바꿔주면 어떤 제품의 DB든 연결할 수 있다. 쿼리를 실행하기 전과 후에 연결 생성, 명령문, ResultSet 닫기등과 같은 많은 코드를 작성해야한다. 또 connection 관리, 예외처리등에 불편함이 있어 나온게 Spring JDBC이다. Spring JDBC -핵심 : JdbcTemplate- Spring JDBC는 JDBC에서 DriveManager가 하는 일들을 JdbcTemplate에게 ..
![article thumbnail](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfqJFQ%2Fbtsl9L1i1gy%2FOqWGSUbwk2fi1DoJzkVbD1%2Fimg.png)
DAO DAO(Data Access Object) 는 데이터베이스의 data에 접근하기 위한 객체이다. DataBase에 접근 하기 위한 로직 & 비지니스 로직을 분리하기 위해 사용한다. DTO DTO(Data Transfer Object) 는 계층 간 데이터 교환을 하기 위해 사용하는 객체로, DTO는 로직을 가지지 않는 순수한 데이터 객체(getter & setter 만 가진 클래스)이다. 데이터 전송 객체 즉, DTO는 기능은 없고 데이터를 전달만 하는 용도로 사용되는 객체를 뜻한다. 참고로 DTO에 기능이 있으면 안되는가? 그것은 아니다. 객체의 주 목적이 데이터를 전송하는 것이라면 DTO라 할 수 있다. 객체 이름에 DTO를 꼭 붙여야 하는 것은 아니다. 대신 붙여두면 용도를 알 수 있다는 장점..
![article thumbnail](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDQSzD%2Fbtsl0VKXxhR%2FfkclKQVqp8dFhrCkndL3m0%2Fimg.png)
1.트랜잭션 문제 2.예외 누수 문제 3.JDBC 반복 문제 트랜잭션 문제 JDBC 구현 기술이 서비스 계층에 누수되는 문제 트랜잭션을 적용하기 위해 JDBC 구현 기술이 서비스 계층에 누수되었다. 서비스 계층은 순수해야 한다. 구현 기술을 변경해도 서비스 계층 코드는 최대한 유지할 수 있어야 한다. (변화에 대응) 그래서 데이터 접근 계층에 JDBC 코드를 다 몰아두는 것이다. 물론 데이터 접근 계층의 구현 기술이 변경될 수도 있으니 데이터 접근 계층은 인터페이스를 제공 하는 것이 좋다. 서비스 계층은 특정 기술에 종속되지 않아야 한다. 지금까지 그렇게 노력해서 데이터 접근 계층으로 JDBC 관련 코드를 모았는데, 트랜잭션을 적용하면서 결국 서비스 계층에 JDBC 구현 기술의 누수가 발생했다. 트랜잭션..
트랜잭션 - 개념 이해 데이터를 저장할 때 단순히 파일에 저장해도 되는데, 데이터베이스에 저장하는 이유는 무엇일까? 여러가지 이유가 있지만, 가장 대표적인 이유는 바로 데이터베이스는 트랜잭션이라는 개념을 지원하기 때문이다. 트랜잭션을 이름 그대로 번역하면 거래라는 뜻이다. 이것을 쉽게 풀어서 이야기하면, 데이터베이스에서 트 랜잭션은 하나의 거래를 안전하게 처리하도록 보장해주는 것을 뜻한다. 그런데 하나의 거래를 안전하게 처 리하려면 생각보다 고려해야 할 점이 많다. 예를 들어서 A의 5000원을 B에게 계좌이체한다고 생각해보자. A의 잔고를 5000원 감소하고, B의 잔고를 5000원 증가해야한다. 5000원 계좌이체 A의 잔고를 5000원 감소 B의 잔고를 5000원 증가 계좌이체라는 거래는 이렇게 2..
![article thumbnail](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIZ6dN%2FbtslMVxPAfp%2FmrkuR5Q4FwcK6PsHMSky9K%2Fimg.png)
데이터베이스 커넥션 데이터베이스 커넥션 풀에 대해 알아보기 이전에 데이터베이스 커넥션이 무엇인지부터 알아봐야한다. 우리가 개발하는 웹 애플리케이션과 데이터베이스는 서로 다른 시스템이다. 따라서 데이터베이스 드라이버를 사용하여 데이터베이스에 연결해야한다. 데이터베이스 연결의 생애주기는 아래와 같다. 1. 데이터베이스 드라이버를 사용하여 데이터베이스 연결 열기 2. 데이터를 읽고 쓰기 위해 TCP 소켓 열기 3. TCP 소켓을 사용하여 데이터 통신 4. 데이터베이스 연결 닫기 5. TCP 소켓 닫기 위와 같이 데이터베이스 연결을 수립하고, 해제하는 과정은 비용이 많이 들어가는 작업이다. 사용자로부터 웹 애플리케이션에 요청이 들어올때마다 데이터베이스 연결을 수립하고, 해제하는 것은 굉장히 비효율적으로 보인다...