DBMS마다 Lock를 구현하는 방식과 세부 적용 방법은 다르지만,
데이터의 접근을 제한함으로써 일관성을 보장하기 위한 방법으로 기본적인 개념은 유사합니다.
DB Lock은 적용 대상과 상황에 따라 분류할 수 있습니다.
Transaction 간의 lock 경합이 발생하여, 작업이 진행되지 않고 멈춰선 상태를 말합니다.
Shared Lock 간에는 발생하지 않지만, Exclusive Lock에선 경합을 하여 우선 순위에 따라 Transaction이 수행됩니다.
이렇게 Blocking 된 Transaction은 lock이 해제 될 때까지 대기하게 되며, 이는 성능에 좋지 않는 영향을 미칩니다.
경합을 최소화하기 위해선 아래의 사항을 준수합니다.
Dead lock(교착 상태)은 두 개 이상의 작업이 서로 상대방의 작업이 끝나길 기다리고 있기 때문에, 결과적으로 아무것도 완료되지 못하는 상태를 말합니다.
Database에서 dead lock은 서로 다른 Transaction 간의 교착 상태를 의미합니다.
DBMS마다 Dead Lock을 관리하는 방법이 상이합니다.
MySQL-innodb 기준으로 아래의 쿼리를 통해 확인 할 수 있습니다.
mysql> show engine innodb status
위 쿼리를 수행하면 현재 innodb의 상태 정보를 표출되며, 최근 발생한 Dead lock 정보를 확인 할 수 있습니다.
만약 모든 deadlock에 대해 확인 하고 싶은 경우, 아래의 설정을 변경합니다.
[my.cnf]
[mysqld]
innodb_print_all_deadlocks = 1
또는
mysql> SET GLOBAL innodb_print_all_deadlocks = 1;
DB Transaction은 DBMS 또는 이와 유사한 시스템에서 사용되는 상호 작용의 단위입니다.
즉, 시스템을 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위로, 한번에 모두 수행되어야 할 일련의 연산들을 의미합니다.
ACID(원자성, 일관성, 고립성, 지속성)는 데이터베이스 Transaction이 안전하게 수행된다는 것을 보장하기 위한 성질을 가리키는 약어입니다.
Transaction은 시스템에 적용하기 위한 연산으로 Commit와 Rollback이 있습니다.
Transaction의 ACID를 엄격하게 준수하면, 데이터의 적합성은 보장 할 수 있지만 동시성 효율은 매우 떨어지게 됩니다.
이러한 Trade-off 관계에서 데이터베이스는 서로 다른 Transaction이 어느 정도 허용이 가능하도록 격리 수준을 지원합니다.
(Level 수준이 높을 수록 엄격한 격리 수준을 제공)
Name | Level | Dirty Read | Non-Repeatable Read | Phantom Read | 정합성 | 동싱성 |
---|---|---|---|---|---|---|
Serializable | 3 | X | X | X | 높다 | 낮다 |
Repeatable Read | 2 | X | X | O | 중간 | 중간 |
Read Committed | 1 | X | O | O | 중간 | 중간 |
Read Uncommitted | 0 | O | O | O | 낮다 | 높다 |
Transaction이 사용 중인 테이블의 모든 Row에 대한 접근을 제한합니다.
이 격리 수준에서는 단순한 Select 쿼리가 실행되더라도, 다른 Transaction이 데이터에 접근 할 수 없습니다.
가장 높은 데이터 접합성을 보장하지만, 그만큼 성능은 가장 느립니다.
Transaction이 Active 될 때 수행한 시간을 기록하고, 해당 시점을 기준으로 consistent read를 수행합니다.
하지만 새로운 Row가 추가 되는 것을 막지는 않습니다.
* consistent read : Read operation을 수행 할 때, 현재 DB의 값이 아닌 특정 시점의 snapshot을 읽어 오는 것
Transaction은 읽기 연산 마다 DB Snapshot를 생성합니다.
이로 인해, 커밋이 완료된 다른 Transaction의 변경 사항은 consistent read 시 반영됩니다.
대부분의 DBMS가 기본 모드로 채택하고 있는 격리 수준입니다.
커밋이 되지 않은 데이터 변경을 다른 Transaction이 조회 가능하도록 허용하는 격리 수준입니다.
데이터 부정합 문제가 발생할 확률은 높아지지만, 그만큼 성능은 가장 빠릅니다.
Spring boot project를 내장 톰캣으로 실행시킬 때 아래의 오류가 발생함.
Error occurred during initialization of VM
Could not reserve enough space for 2097152KB object heap
해당 오류는 프로젝트 실행 시 heap 메모리가 부족하다는 오류입니다.
Help > Change Memory Settings
-Xms1024m -Xmx2048m
The maximum theoretical heap limit for the 32-bit JVM is 4G.
Due to various additional constraints such as available swap, kernel address space usage, memory fragmentation, and VM overhead, in practice the limit can be much lower.
On most modern 32-bit Windows systems the maximum heap size will range from 1.4G to 1.6G. On 32-bit Solaris kernels the address space is limited to 2G. On 64-bit operating systems running the 32-bit VM, the max heap size can be higher, approaching 4G on many Solaris systems.
32bit JVM은 이론상 최대 4GB의 메모리를 사용 할 수 있지만, Windows 환경에선 2GB로 제한됩니다. 이로 인해 2GB 이상의 프로젝트를 실행 할때 해당 오류가 발생 한 것입니다.
HTTP Cookie는 서버에 의해 브라우저에 저장되는 데이터 조각입니다.
Cookie는 2개의 유형으로 나뉩니다.
Http는 connectionless & Stateless(무상태성, 상태 정보를 가지 않는) 프로토콜입니다.
서버는 요청한 클라이언트의 상태 정보를 알 수 없기 때문에, 매번 인증 절차를 수행해야 합니다.
HTTP는 HyperText Transfer Protocol의 약자로,
1989년 월드 와이드 웹이 개발되면서 데이터 전송을 위한 프로토콜입니다.
원라인 프토로콜로도 불리는 HTTP/0.9는 HTTP/1.0 이전의 프로토콜을 명시하기 위한 버전입니다. (HTTP/1.0 이전에는 별도로 버전 번호를 부여하지 않았으나, HTTP/1.0과 구분하기 위함)
HTTP/0.9는 요청 메서드가 GET만 존재하였으며, 매우 단순한 구조의 프로토콜입니다.
프로토콜 확장을 위한 여러 노력들이 반영되었습니다.
그 외에 여러 새로운 기능들을 시도하였으며 이러한 내용을 RFC 1945(1996년 11월)에 공개되었습니다.
최초의 표준 프로토콜로 RFC 2068(1997년 1월)에 처음 공개되으며,
HTTP/1.0의 모호함을 명확하게 정의하고 많은 개선 사항들을 적용하였습니다.
더 나은 성능을 위한 프로토콜입니다.
TCP/TSL가 아닌 QUIC를 사용합니다.
QUIC(Quick UDP Internet Connection) : 범용 목적의 전송계층 통신 프로토콜로서, TCP가 아닌 UDP를 이용하여 다중화 연결을 지원하는 방식입니다.
HTTP Request(요청)하고 이에 대한 Respone(응답)을 순차적으로 처리하지 않는 통신 방법입니다.
비동기식은 Requset와 이에 대한 Respone을 순차적으로 처리하는 동기식에 비해, 여러 요청을 동시에 수행할 수 있어 많은 이점이 있습니다.
이러한 이점을 통해
Asynchronous Javascript And XML의 약자로 “에이젝스” 또는 “아작스”라고 읽습니다.
jqery에서 제공하는 ajax()와 혼돈하는 경우가 많은데,
javascript로 XMLHttpRequest 객체를 이용해 서버와 클라이언트가 비동기로 통신하는 기법
을 말합니다.
WHATWG에서는 이러한 Ajax를 구현하기 위해 XMLHttpRequset 또는 Fetch 를 표준으로 관리하고 있습니다.
XMLHttpRequest는 Internet Explorer의 XMLHTTP라고 불리는 ActiveX 기술로부터 시작되지만, 현재는 대부분의 브라우저에서 지원을 하고 있습니다.
XMLHttpRequest 인터페이스는 이용해 서버와 클라이언트가 비동기로 통신을 수행하이름에 XML이 들어가지만 모든 종류의 데이터를 담을 수 있습니다.
아래는 순수한 javascript로 ajax를 구현하는 예시입니다.
// httpRequest.readyState에 대한 처리 처리 구현
function responeFunction() {}
// XMLHttpRequest 객체 생성
const httpRequest = new XMLHttpRequest();
// HTTP 요청의 상태가 변경 되었을 때 수행 될 함수 지정
httpRequest.onreadystatechange = responeFunction;
// HTTP 요청 정보 설정
httpRequest.open("GET", "test.json");
// HTTP 요청
httpRequest.send();
XMLHttpRequest를 이용한 AJAX는 복잡하기도 하고, 가독성이 좋지 않습니다.
이를 보완하기 위해 ES6부터 Fetch를 지원하기 시작하였습니다.
Fetch API는 HTTP 파이프라인을 구성하는 요청과 응답 등의 요소를 Javascript에서 제어할 수 있도록 인터페이스를 제공합니다.
fetch는 매우 간단하게 구현 할 수 있습니다.
// HTTP 요청
fetch("http://test.json").then((response) => console.log(response.json())); // 응답 처리