데이터베이스 커넥션을 획득할 때는 아래와 같은 복잡한 과정을 거친다.애플리케이션 로직은 DB 드라이버를 통해 커넥션을 조회한다.DB 드라이버는 DB와 TCP/IP 커넥션을 연결한다. 물론 이 과정에서 3 way handshake 같은 TCP/IP 연결을 위한 네트워크
DriverManager를 통해서 커넥션을 획득하다가 커넥션 풀을 사용하는 방법으로 변경하려면 어떻게 해야할까?예를 들어서 애플리케이션 로직에서 DriverManager를 사용해서 커넥션을 획득하다가 HikariCP 같은 커넥션 풀을 사용하도록 변경하면 커넥션을 획득하
데이터를 저장할 때 단순히 파일에 저장해도 되는데 데이터베이스에 저장하는 이유는 무엇일까?가장 대표적인 이유는 데이터베이스가 트랜잭션이라는 개념을 지원하기 때문이다.트랜잭션을 이름 그대로 번역하면 거래라는 뜻이다.데이터베이스에서 트랜잭션은 하나의 거래를 안전하게 처리하
사용자는 웹 애플리케이션 서버(WAS)나 DB 접근 툴 같은 클라이언트를 사용해서 데이터베이스 서버에 접근할 수 있다. 클라이언트는 데이터베이스 서버에 연결을 요청하고 커넥션을 맺게 된다. 이때 데이터베이스 서버는 내부에 세션이라는 것을 만든다.그리고 앞으로 해당 커넥
데이터 변경 쿼리를 실행하고 데이터베이스에 그 결과를 반영하려면 커밋 명령어인 commit을 호출하고결과를 반영하고 싶지 않으면 롤백 명령어인 rollback을 호출하면 된다.커밋을 호출하기 전까지는 임시로 데이터를 저장하는 것이다. 따라서 트랜잭션을 시작한 세션(사용
자동 커밋으로 설정하면 각각의 쿼리 실행 직후에 자동으로 커밋을 호출한다.따라서 커밋이나 롤백을 직접 호출하지 않아도 되는 편리함이 있다. 하지만 쿼리를 하나하나 실행할 때마다 자동으로 커밋이 되어버리기 때문에 우리가 원하는 트랜잭션 기능을 제대로 사용할 수 없다. 따
아직 세션1이 커밋을 하지 않은 상태이기 때문에 세션1에서는 입력한 데이터가 보이지만세션2에서는 입력한 데이터가 보이지 않는 것을 확인할 수 있다. 세션1이 트랜잭션을 커밋했기 때문에 데이터베이스에 실제 데이터가 반영된다. 커밋 이후에는 모든 세션에서 데이터를 조회할
계좌이체 정상계좌이체 문제 상황 - 커밋계좌이체 문제 상황 - 롤백 memberA의 돈을 memberB에게 2000원 계좌 이체 하는 트랜잭션을 실행해보자. 2번의 update 쿼리가 수행되어야 한다. set autocommit false로 설정한다. 아직 커밋하지 않
세션1이 트랜잭션을 시작하고 데이터를 수정하는 동안 아직 커밋을 수행하지 않았는데세션2에서 동시에 같은 데이터를 수정하게 되면 여러가지 문제가 발생한다.바로 트랜잭션의 원자성이 깨지는 것이다. 여기에 더해서 세션1이 중간에 롤백을 하게 되면 세션2는 잘못된 데이터를 수
세션1이 트랜잭션을 시작하고 memberA의 데이터를 500원으로 업데이트 했다. 아직 커밋은 하지 않았다.memberA 로우의 락은 세션1이 가지게 된다. 세션2는 memberA의 데이터를 1000원으로 수정하려 한다.세션1이 트랜잭션을 커밋하거나 롤백해서 종료하지
데이터베이스마다 다르지만 보통 데이터를 조회할 때는 락을 획득하지 않고 바로 데이터를 조회할 수 있다. 예를 들어서 세션1이 락을 획득하고 데이터를 변경하고 있어도 세션2에서 데이터를 조회는 할 수 있다. 물론 세션2에서 조회가 아니라 데이터를 변경하려면 락이 필요하기
트랜잭션은 비즈니스 로직이 있는 서비스 계층에서 시작해야 한다.비즈니스 로직이 잘못되면 해당 비즈니스 로직으로 인해 문제가 되는 부분을 함께 롤백해야 하기 때문이다. 그런데 트랜잭션을 시작하려면 커넥션이 필요하다.결국 서비스 계층에서 커넥션을 만들고 트랜잭션 커밋 이후
트랜잭션은 사실 단순하다.트랜잭션을 시작하고 비즈니스 로직의 수행이 끝나면 커밋하거나 롤백하면 된다.그리고 TxManager 인터페이스를 기반으로 각각의 기술에 맞는 구현체를 만들면 된다.JdbcTxManager : JDBC 트랜잭션 기능을 제공하는 구현체JpaTxMa
트랜잭션을 유지하려면 트랜잭션의 시작부터 끝까지 같은 데이터베이스 커넥션을 유지해야 한다.결국 같은 커넥션을 동기화(맞추어 사용)하기 위해서 이전에는 파라미터로 커넥션을 전달하는 방법을 사용했다.하지만 파라미터로 커넥션을 전달하는 방법은 코드가 지저분해지는 것은 물론이
클라이언트의 요청으로 서비스 로직을 실행한다.서비스 계층에서 transactionManager.getTransaction()을 호출해서 트랜잭션을 시작한다.트랜잭션을 시작하려면 먼저 데이터베이스 커넥션이 필요하다. 트랜잭션 매니저는 내부에서 데이터소스를 사용해서 커넥션
프록시를 도입하기 전에는 기존처럼 서비스의 로직에서 트랜잭션을 직접 시작한다. 프록시를 사용하면 트랜잭션을 처리하는 객체와 비즈니스 로직을 처리하는 서비스 객체를 명확하게 분리할 수 있다. 프록시 도입 전 : 서비스에 비즈니스 로직과 트랜잭션 처리 로직이 함께 섞여있다