COMMIT 하나의 트랜잭션 작업이 성공적으로 끝났고, 로그가 정상적으로 남았다라는 것을 알려주는 것
ROLLBACK 트랜잭션 작업 중 비정상적으로 종료되거나, 원자성이 깨진 경우 그 전 상태로 돌아가는 작업
개발에서의 트랜잭션
DB접근이 발생하는 여러 단위 작업들을 의미있는 그룹으로 묶어서 일괄 커밋 또는 일괄 롤백하는 매커니즘을 뜻한다.
- 어노테이션 방식으로 @Transactional을 선언하여 사용한다. = 선언적 트랜잭션 - JDBC, MyBatis 등을 사용할 때는DataSourceTransactionManager를 관리자로 등록한다. 이 클래스는 dataSource 프로퍼티를 통해 전달받은 Connection으로 커밋, 롤백을 수행하면서 관리한다.
Spring에서 Transaction 설정하기
스프링에서는 트랜잭션 처리를 지원하는데, 그 중 annotation 방식으로 ( @Transactional ) 을 선언하여 사용하는 방법을 선언적 트랜잭션이라고 한다
클래스 전체나 메소드 단위로 @Transactional 을 적용하면 (AOP) , 트랜잭션 기능이 적용된 프록시 객체가 생성된다.
CheckedException 이나 예외가 없을 때는 Commit 하고, UncheckedException 이 발생하면 Rollback 한다.
주의사항
@Transactional은 우선순위를 가지고 있다 클래스 method에 선언된 트랜잭션의 우선순위가 가장 높고, 인터페이스에 서언된 트랜잭션 우선순위가 가장 낮다.
클래스 메소드 > 클래스 > 인터페이스 메소드 > 인터페이스
인터페이스 기반 프록시에서만 유효한 트랜잭션이 설정된다
자바 어노테이션은 인터페이스로부터 상속되지 않기 때문에, 클래스 기반 프록시나 Aspect J기반에서 트랜잭션을 인식할 수 없다.
스프링 트랜잭션의 기본모드인 proxy 모드에서는 오직 외부로부터 method 호출이 발생한 경우에만 method가 인터셉트 되어 트랜잭션 관리가 적용된다. (오브젝트 내의 한 method가 동일 오브젝트 내의 다른 method를 호출할 경우에는 호출 당한 method가 @Transctional이 붙어 있다고 해도, 적용되지 않는다. 위빙되어 있는 method를 부르는게 아니니깐.)
1. try / catch는 필수 2. try / catch를 잡아놓고 catch부분에 아무것도 작성하지 않는게 더 안좋음 3. throws를 통해 에러처리를 넘기는데 어디선가는 꼭 해야함 4. throws로 에러 책임을 넘기는게 무조건 나쁜건 아니고 상황에 맞게 사용해야함 5. Exception종류는 최대한 세세하게 선언해야함. 6. catch는 여러번 사용이 가능한데 상속 개념을 생각해서 사용해야함. (자바7부터) (위에 있는 catch의 Exception이 다음 catch보다 큰 개념이면 다음 catch까지 도달하지 못하기 때문) 7. 예외처리는 트랜젝션과 관계가 있다. 어디에서 예외처리를 하냐에 따라 롤백을 하느냐 마느냐를 정한다. 뭔가가 잘못되면 모든 작업을 중단해야하는데 예외처리를 잘못하면 뭐는 진행되고 뭐는 멈추고 해서 데이터가 뒤죽박죽 된다.
예외처리 사용자의 실수든 환경의 오류든 코드가 제대로 실행되지 않는 경우가 있는데 예외처리를 하지 않으면 프로그램은 끝까지 실행되지 않고 중간에 멈춰버리게 된다. 그 에러 하나 때문에 프로그램이 멈추는 걸 방지하기 위해 예외처리를 한다. 예외처리를 하게 되면 프로그램이 돌다가 에러가나서 예외처리한 부분을 만나게 되면 개발자가 정해놓은 방법으로 넘어가서 프로그램이 멈추지 않게 된다.
예외가 일어날 것 같은 곳에 try, catch를 걸어준다. try는 실행되어야 할 코드를 작성하고 catch에는 에러가 났을때 처리해야할 작업을 작성한다.
근데 catch부분에 예외에 대한 상황을 적어야 한다. 계산이 잘못된예외인지, 배열에서 벗어난 값을 찾는 예외인지
catch에 예외의 종류를 적고 보통 e를 적는다
사진처럼 e가 있는데 이걸 이용해서 오류 메세지를 확인할 수 있다 e.getMessage(), e.printStackTrace() 이런 명령어를 통해 오류의 메세지를 출력할 수 있다. 근데 이런 에러메세지는 위 사진처럼 바로 보이게 하면 보안? 관련에 문제가 생길 수 있기 때문에 로깅시스템 같은걸 이용해서 따로 에러를 모아둬야 한다.
(자세하게) e.printStackTrace() > e.getMessage() > e.toString() (간단하게) 순으로 에러에 대한 내용이 자세하게 나온다.
try / catch 는 마지막에 finally를 선택적으로 넣을 수 있다. (넣어도 되고 안넣어도 되고) finally부분은 오류가 발생했든 안했든 반드시 실행되는 부분이다.
오류가 날것 같은곳에 개발자가 직접 try/catch를 잡아줘서 예외처리를 잡아줘야 하는데
오류를 처리하지않고 디바이드 메서드를 호출한 쪽에게 오류를 처리하라고 떠넘길 수 있는데 그 키워드가 throws다.
2번에 try/cathch를 사용해서 오류를 잡을 수 있지만 throws를 이용해서 2번에서 오류를 처리하지 않고 2번을 부르는 1번에 오류처리를 떠넘길 수 있다. 그리고 오류처리는 ,를 통해 여러개를 지정할 수 있다.
근데 1번 메소드에서 try/catch를 사용해야 한다.
에러는 어쩔 수 없는거 exception은 내가 잘하면 처리할 수 있는 것 exception은 Checked Exception과 UnChecked Exception으로 나눌 수 있다.
throw는 예외를 발생시키는것
throws는 예외를 던지는 것
throws는 메소드 선언부 끝에 작성한다.
method1에서 method2를 부른다. 그리고 method2에 throws를 작성했다. 저 코드상 method2에는 에러가 나야하는데 try/catch가 없는데도 빨간줄이 없다. 이유는 method2의 선언부에 throws를 작성했기 때문에 ClassNotFoundException이 발생한다면 method2를 부른 부분에서 처리하라는 의미가 된다. 그래서 method2를 부른 method1에서 예외를 처리해야한다. 그리고 그곳에 try/cathch가 있다.
throw는 메소드 내에서 상위 블럭으로 예외를 던지는 것 throws는 현재 메소드에서 상위 메소드로 예외를 던진다.
throw는 억지로 에러를 발생시킬때도 사용되지만 현재메소드의 에러를 처리한 후에 상위 메소드에 에러정보를 줌으로써 상위 메소드에서도 에러기 발생한것을 감지할 수 있다.
throw를 쓰는 이유? (내생각)
강제로 에러를 일으키는 throw를 왜 쓸까? 하는 생각을 하던중 아래 링크를 찾았다.
일정 로직에서 벗어나면 throw를 거쳐서 강제로 에러를 내게 할 수 있다. 개발자가 일정 규칙에 따라 코드를 만드는데 사용자가 다르게 사용하거나 수작을 부릴것 같다하면 조건문을 통해 일정 조건을 벗어나면 강제로 throw를 만나게해서 에러를 일으킬 수 있다.
pc사야중에 4코어 8쓰레드, 8코어 16쓰레드라는게 있는데 쓰레드는 일을 하는 녀석인데 8쓰레드는 일하는 녀석이 8개 16쓰레드는 일하는 녀석이 16개
1코어 1쓰레드
2코어 2쓰레드
4코어 4쓰레드
4코어 8쓰레드
쉽게 이렇게 생각하면된다
양손이 1쓰레드
일을 할때 하나의 스레드에서 하면 한작업이 끝날때까지 다른 작업을 하지 못하기 때문에 속도가 느려진다.
스레드가 많아지면 한번에 2가지 4가지 일을 할 수 있기 때문에 속도가 빨라진다.
동기 VS 비동기
비동기
작업을 다른 스레드로 보내는게 비동기 (여러개의 스레드가 돌아가서 작업을 처리한다) 동시에 일을 할 수 있다. - 작업을 다른 스레드에서 하도록 시킨 후. 그 작업이 끝나길 '안기다리고' 다음일을 진행한다. (안 기다려도 다음 작업을 생성할 수 있다.)
동기
작업을 다른 스레드로 보내지 않고 하나의 스레드에서 작업을 하는거 (하나의 스레드에서 차례대로 작업을 하는것) 동시에 일을 하지 않는다. - 작업을 다른 스레드에서 하도록 시킨 후, 그 작업이 끝나길 '기다렸다가' 다음일을 진행한다. (기다렸다가 다음 작업을 생성할 수 있다.)
비동기 라는 개념이 일반적으로 필요한 이유는 서버와의 통신 때문
직렬 (Serial) VS 동시 (Concurrent)?
직렬(Serial) 처리 (보통 메인에서) 분산처리 시킨 작업을 '다른 한개의 쓰레드에서' 처리 순서가 중요한 작업을 처리할 때 사용
동시(Cocurrent) 처리 (보통 메인에서) 분산처리 시킨 작업을 '다른 여러개의 쓰레드에서' 처리 각자 독립적이지만 유사한 여러개의 작업을 처리할 때 사용
분산처리 하려는거면 무조건 동시( Concurrent)처리'가 무조건 좋아 보이는데 왜 직렬 (Serial)처리가 필요할까?
작업에 순서가 필요한 경우가 있기 때문이다. 무조건 1번이 끝나고 2번이 실행되야 하는 경우
동시처리의 예
당근마켓 어플에서 목록을 봤을때 물건의 이미지를 하나씩 다 서버에서 가져올때 그 하나 하나가 동시처리
2. 가상선택자 a1:after{contnent:""; display:block; clear:both;} 클래스명이 a1인 곳에 가상선택자인 after를 준다. 이게 :after앞에 있는 a1클래스의 블록 마지막에 content를 넣는건데 content는 span이라고 보면 된다 가로 높이가 0인걸 자동으로 넣는거고 display:block;때문에 속성이 블록으로 되고 clear:both; 까지 해줘서 float 같은거 때문에 초기화 할때 사용
다중클래스
a태그로 생기는 밑줄 없애는 방법은 a태그에다 text-decoration:none을 주면 밑줄이 사라진다.
들여쓰기 text-indent: Xpx; 는 첫줄에만 적용된다
text-align 에는 left, right, center, justify가 있는데 justify는 양쪽으로 꽉차게 만든다.
div 태그 안에 따로 있는 태그의 클래스 명을 지정하는게 아니라 div태그에 공통으로 글자색을 검은색으로 했는데 div태그중 하나에 class 이름을 주고 그거 하나만 빨간색을 하고싶다! 할대 사용하면 됨 div자식태그가 p인지 div인지는 중요하지 않고 클래스명만 찾아서 적용한다