트랜잭션

· Redis
개요 Spring 프로젝트 같은 멀티 쓰레드 환경에서는 동시성 처리가 필요한 상황이 발생합니다. 서버가 1대라면 쓰레드 동기화를 통해 처리가 가능하지만, 서버가 여러대로 늘어난다면 요청이 분산되기 때문에 무용지물이 됩니다. 만약 쇼핑몰에서 재고가 1개인 상품을 2명의 회원의 동시에 주문한 경우 2번에 요청에서 상품을 조회 당시에는 재고가 1개이므로 2명의 회원 모두 주문에 성공하는 경우가 발생할 수 있습니다. ZooKeeper나 MySQL 분산락을 사용할 수 있지만 Redis를 도입하고있고, 예정이라면 Redis를 통해 분산락으로 동시성 처리가 가능합니다. 라이브러리 선택 Redis를 이용해 분산락을 사용하기 전에 고려해야 할 것이 있는데 어떠한 라이브러리를 사용할 것인가 입니다. Spring에서 제공하..
· JPA
트랜잭션은 ACID라 하는 원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 지속성(Durability)을 보장해야 한다. 원자성 트랜잭션 내에서 실행한 적업들은 마치 하나의 작업인 것처럼 모두 성공 또는 모두 실패해야 한다. 일관성 모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야 한다. 예를 들어 데이터베이스에서 정한 무결성 제약 조건을 항상 만족해야 한다. 격리성 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다. 예를 들어 동시에 같은 데이터를 수정하지 못하도록 해야한다. 격리성은 동시성과 관련된 성능 이슈로 인해 격리 수준을 선택할 수 있다. 지속성 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 한다. 중간에 시스템에 문제..
· JPA
트랜잭션을 지원하는 쓰기 지연과 JDBC 배치 insert(member1); // INSERT INTO ... insert(member2); // INSERT INTO ... insert(member3); // INSERT INTO ... insert(member4); // INSERT INTO ... insert(member5); // INSERT INTO ... commit(); 위와 같은 경우는 5번에 INSERT SQL과 1번의 커밋으로 총 6번 데이터베이스와 통신한다. 이것을 최적화 하려면 SQL을 모아 한 번에 데이터베이스로 보내면 된다. JDBC가 제공하는 SQL 배치 기능을 사용하면 SQL을 모아서 데이터베이스에 한 번에 보낼 수 있다. 하지만 이 기능을 사용하려면 코드의 많은 부분을 수정..
· JPA
엔티티가 영속성 컨텍스트에 관리되면 1차 캐시부터 변경 감지까지 얻을 수 있는 혜택이 많다. 하지만 영속성 컨텍스트는 변경 감지를 위해 스냅샷 인스턴스를 보관하므로 더 많은 메모리르 사용하는 단점이 있다. 예를 들어 100건의 구매 내용을 출력하는 단순한 조회 화면이 있다고 가정해보자. 그리고 조회한 엔티티를 다시 조회할 일도 없고 수정할 일도 없이 딱 한 번만 읽어서 화면에 출력하면 된다. 이때는 읽기 전용으로 엔티티를 조회하면 메모리 사용량을 최적화할 수 있다. 스칼라 타입으로 조회 가장 확실한 방법은 다음처럼 엠티티가 아닌 스칼라 타입으로 모든 필드를 조회하는 것이다. 스칼라 타입은 영속성 컨텍스트가 결과를 관리하지 않는다. select o.id, o.name, o.price from Order o..
· JPA
엔티티의 동등성 비교 영속성 컨텍스트 내부에는 엔티티 인스턴스를 보관하기 위한 1차 캐시가 있다. 이 1차 캐시는 영속성 컨텍스트와 생명주기를 같이 한다. 영속성 컨텍스트를 통해 데이터를 저장하거나 조회하면 1차 캐시에 엔티티가 저장된다. 이 1차 캐시 덕분에 변경 감지 기능도 동작하고, 이름 그대로 1차 캐시로 사용되서어 데이터베이스를 통하지 않고 데이터를 바로 조회할 수도 있다. 영속성 컨텍스트를 더 정확히 이해하기 위해서는 1차 캐시의 가장 큰 장점인 애플리케이션 수준의 반복 가능한 읽기를 이해해야 한다. 같은 영속성 컨텍스트에서 엔티티를 조회하면 다음 코드와 같이 항상 같은 엔티티 인스턴스를 반환한다. 단순이 동등성 비교 수준이 아니라 정말 주소값이 같은 인스턴스를 반환한다. Member memb..
· JPA
JPA 표준 예외 정리 JPA 표준 예외들은 javax.persistence.PersistenceException의 자식 클래스다. 그리고 이 예외 클래스는 RuntimeException의 자식이다. 따라서 JPA 예외는 모두 언체크 예외다. JPA 표준 예외는 크게 2가지로 나눌 수 있다. 트랜잭션 롤백을 표시하는 예외 트랜잭션 롤백을 표시하지 않는 예외 트랜잭션 롤백을 표시하는 예외는 심각한 예외이므로 복구해선 안 된다. 이 예외가 발생하면 트랜잭션을 강제로 커밋해도 트랜잭션이 커밋되지 않고 대신에 javax.persistence.RollbackException 예외가 발생한다. 반면에 트랜잭션 롤백을 표시하지 않는 예외는 심각한 예외가 아니다. 따라서 개발자가 트랜잭션을 커밋할지 롤백할지를 판단하면..
· JPA
순수하게 J2SE 환경에서 JPA를 사용하면 개발자가 직접 엔티티 매니저를 생성하고 트랜잭션도 관리해야 한다. 하지만 스트링이나 J2EE 컨테이너 환경에서 JPA를 사용하면 컨테이너가 제공하는 전략을 따라야 한다. 스프링 컨테이너의 기본 전략 스프링 컨테이너는 트랜잭션 범위의 영속성 컨텍스트 전략을 기본으로 사용한다. 이 전략은 이름 그대로 트랜잭션의 범위와 영속성 컨텍스트의 생존 범위가 같다는 뜻이다. 트랜잭션을 시작할 때 영속성 컨텍스트를 생성하고 트랜잭션이 끝날 때 영속성 컨텍스트를 종료한다. 그리고 같은 트랜잭션 안에서는 항상 같은 영속성 컨텍스트에 접근한다. 스프링 프레임워크를 사용하면 보통 비즈니스 로직을 시작하는 서비스 계층에 @Transactional 어노테이션을 선언해서 트랜잭션을 시작한..
· DDD
애그리거트와 트랜잭션 한 애그리거트가 여러곳의 호출에 의해 동시에 변경이 되는 걸 방지하기 위해 트랜잭션 처리 기법이 필요하다. 트랜잭션 처리 방식에는 선점(Pessimistic) 잠금과 비선점(Optimistic) 잠금 두 가지 방식이 있다. 선점(Pessimistic) 잠금 선점 잠금이란 먼저 애그리거트를 구한 스레드가 애그리거트 사용이 끝날때까지 다른 스레드가 해당 애그리거트를 수정하는 것을 막는 방식이다. 스레드1이 애그리거트를 수정하는 동안 블록킹이 되고 트랜잭션이 커밋되는 대기하고 있던 스레드2가 작동한다. 선점 잠금은 보통 DBMS가 제공하는 행 단위 잠금을 사용해서 구현한다. JPA의 EntityManager는 LockModeType을 인자로 받는 find() 메서드를 제공하는데, Lock..
· DDD
애그리거트란? 관련된 객체를 하나로 묶은 군집 도메인이 커질수록 개발할 도메인 모델도 커지면서 엔티티와 밸류가 많아질수록 모델은 점점 복잡해진다. 개별 도메인 모델에만 집중하다 보면 큰 수준에서 모델을 이해하지 못해 큰 틀에서 모델을 관리 할 수 없게 된다. 도메인 모델을 개별 객체뿐만 아니라 상위 수준에서 모델을 볼 수 있어야 이해하는데 도움이 된다. 그러므로 애그리거트로 관련된 객체를 묶어 전체적인 모델의 이해를 돕는다. 애그리거트 구성할때 주의할점! 한 애그리거트에 속한 객체는 다른 애그리거트에 속하지 않는다. 각 애그리거트는 독립적이며 자기 자신만 관리할 뿐 다른 애그리거트를 관리하지 않는다. 함께 생성되고 제거되는 구성요소는 한 애그리거트에 속할 가능성이 높다.(같은 라이프 사이클) 함께 변경되..
beekei
'트랜잭션' 태그의 글 목록