분류없음2019.02.26 12:00

https://blog.outsider.ne.kr/702


안됨


https://code.i-harness.com/ko-kr/q/a5d3c0

'set -g mouse on'



Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

DATABASE2018.12.22 19:52

이노디비 데드락 패턴


상호거래 데드락

트랜잭션 1에서 userId='A'에게 배타적 잠금 상태

트랜잭션 2에서 userId='B'에게 배타적 잠금 상태

이 상태에서 양쪽으로 배타적 잠금 요청시 발생.


유니크 인덱스 관련

트랜잭션 1,2,3이 다음과 같은 insert문 동시 실행

insert into tb values(9)


1번이 먼저 배타적 잠금을 가지고 있고, 그렇기에 트랜잭션 2,3번은 공유잠금을 획득하기 위해 대기.

1번이 롤백할 경우 가상의 레코드에 공유잠금을 획득, 그러나 없다는걸 알게되고 insert를 위해 2,3번이 동시에 배타적 잠금을 걸려고 시도.

하지만 두개의 트랜잭션이 모두 공유잠금 상태이기때문에 아무도 못걸고 데드락 발생.

http://kuaaan.tistory.com/100


외래키 잠금

a, b 두 테이블이 있고 b가 a의 키를 외래키로 참조.

b에 insert시 a에는 공유잠금이 걸림(외래키로인해)

이 상황에서 1번 트랜잭션이 a를 업뎃, 2번 트랜잭션이 a를 업뎃 하고자 하면..

위 유니크 인덱스패턴처럼 데드락이 발생


서로다른 인덱스로 인한 잠금

인덱스가 여러개일때(ex보조인덱스 1개, 기본키 1개)

하나의 업뎃문이 보조인덱스로 잠그고, 다른 업뎃문이 기본키로 잠그려고 하면

결국 동일한 레코드에대한 잠금 경합이 발생할 수 있음.


https://www.letmecompile.com/mysql-innodb-lock-deadlock/

http://gywn.net/2012/05/mysql-transaction-isolation-level/

https://m.blog.naver.com/PostView.nhn?blogId=reinstate10&logNo=130177937622&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F



낙관적 락

어플리케이션이 제공하는 락, 기본적으로 모든 요청은 업데이트를 시도한다.

하지만 시도 이후 잘못된 경우(버전 정보등이 안맞음) 잘못된 요청들을 모두 실패 시키는 방식.


비관적 락.

충돌이 날 것으로 가정하고 업데이트할 row에 일단 락을 걸고 시작.

한개의 row에 대해 여러 요청이 들어오는 경우 다른 요청들은 첫번째 요청이 락을 풀기 대기(보통 타임아웃 시간이 있고 시간이 지나면 실패로 들어감)

앞의 요청이 작업을 마치면 그다음 요청이 실행된다.

'DATABASE' 카테고리의 다른 글

데드락  (0) 2018.12.22
DB MySQL을 중심으로(innoDB엔진)  (0) 2018.12.13
[DB & JSP] 각 Database 별 커넥션 풀 설정(계속 업데이트)  (0) 2011.11.08
Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

참고 자료들2018.12.13 12:13

HA, 고 가용성. 서비스 가용율을 95%, 99.9% 보장 등등을 위해 HA를 구성한다고 한다.


로드밸런싱

L4, L7 스위치

Fault Tolerance

failover



http://tansfil.tistory.com/58

https://www.lesstif.com/pages/viewpage.action?pageId=46366798

https://d2.naver.com/helloworld/284659

https://d2.naver.com/helloworld/605418

https://12bme.tistory.com/196

http://kimstar.kr/blog/wp-content/uploads/2014/11/%EC%84%9C%EB%B2%84%EC%9D%B4%EC%A4%91%ED%99%94.pdf

'참고 자료들' 카테고리의 다른 글

HA 구성  (0) 2018.12.13
Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

DATABASE2018.12.13 01:50

지연된 쓰기

일반 적인 사용 DBMS들의 경우 대부분 지연된 쓰기를 지원.

Insert, Update, Delete를 버펄이 후 일괄처리한다.


메모리

운영체제에 따라 실제 할당되는 메모리 계산이 쉽지 않다.

단순히 mysql 설정 파라미터로 할당해둔 메모리양을 항상 할당되었다고 생각하는것이 편하다.


쿼리 실행구조

쿼리를 요청하면

1. 쿼리 파서가 쿼리 문장을 토큰(msql이 인식하는 최소 단위)으로 분리해 트리 형태의 구조로 만듬

2. 전처리기 : 파서트리를 기반으로 구조적 문제가 있는지 확인. 각 토큰을 테이블 이름이나 칼럼이름 내장함수와 같은 개체를 매핑해 각각의 존재여부와 접근권한을 확인.

3. 옵티마이저 : 들어온 쿼리문장을 저렴한비용으로 가장 빠르게 처리할 방법을 찾는다.

4. 실행 : 옵티마이저에 의해 나온 실행 계획대로 각 핸들러에게 요청해서 받은 결과를 또 다른 핸들러 요청으로 입력을 연결한다.


복제

마스터 : 바이너리 로그 스레드 -> 바이너리 -> 바이너리 로그 덤프 스레드

슬레이브 : 리플리케이션 I/O 스레드(덤프를 받아옴) -> 릴레이로그 -> 리플리케이션 SQL 스레드 -> 데이터 파일


문장기반 복제(Statement) : 마스터에서 실행된 SQL을 그대로 실행. Repeatable Read 이상의 트랜잭션 격리수준이 요구되어 갭락이나 넥스트 키락이 필요. 느려질 수 있으나 네트웍 비용은 적음

레코드기반 복제(Row Based) : 변경된 레코드를 바이너리 로그에 기록. 네트웍 비용이 커질 수 있으나 read-committed 격리수준에서도 사용가능. 잠금 경합도 줄어듬.


언두로그

변경전 데이터를 보관한다. 롤백 대비용. 격리수준을 유지하면서 동시성 제공에도 사용


인서트 버퍼

인덱스가 많아 인덱스 업뎃이 필요한경우, 바로 인서트 업데이트를 실행하지 않고 임시 공간에 저장하고 사용자에게 결과를 반환하는 형태로 성능을 향상시킨다.

단 전달전 중복여부를 체크해야하는 유니크인덱스는 인서트 버퍼 사용불가.


리두 로그 및 버퍼

ACID 보장을 위해 변경 내용을 순차적으로 디스크에 기록하는 로그 파일


MVCC(Multi Version Concurrency Control)

가장큰 목적은 잠금을 사용하지 않는 일관된 읽기를 제공하는 것

상황에 따라 버퍼풀이나 데이터파일의 내용을 반환할지, 언두로그의 내용을 반환할지 선택

격리 수준에 따라 달라진다.


잠금없는 일관된 읽기

read-uncommited, read-commited, repeatale-read 격리수준에서 select는 잠금을 대기하지 않고 바로 실행되는 것.

변경이 있을경우 언두로그를 사용




트랜잭션 격리수준

글로벌 락

Flush tables with read lock 명령으로만 획득 가능. 가장 범위가 큰 잠금.

다른 세션에서 select를 제외한 대부분의 ddl문장이나 dml문장 실행이 대기 상태가 됨.

Flush tables with read lock는 락을 걸기전 테이블을 flush해야하기 때문에 그 전의 모든 쿼리가 완료되어야 한다.

따라서 오래 걸리는 select쿼리가 있거나 하면 select 쿼리가 끝나기까지 기다리느라 insert,update,delete 가 실행되지 못하고 오래 대기하게 된다.

실시간 웹 서비스에선 사용해선 안됨


테이블락

개별 테이블 단위로 설정되는 락, 명시적 or 묵시적으로 락 획득 가능.

명시적, - LOCK TABLES table_name [READ|WRITE] 명령으로 획득

명시적 락의 경우 UNLOCK TABLES 명령으로 해제 해야 한다. 명시적 락은 특별한 경우 아니면 사용을 많이 하지 않은다.

비용이 비쌈.


묵시적 락의 경우 테이블을 변경하는 쿼리를 실행하면 발생. 변경되는 테이블에 락을 걸고 끝나면 즉사 해제한다.

다만 innoDB의 경우 스토리지 엔진 차원에서 레코드기반의 자금을 제공하기 때문에 묵시적인 테이블 락이 설정되지는 않는다.

정확하는 테이블락이 설정되지만 대부분의 DML에선 무시되고 DDL의 경우 영향을 끼친다.


유저 락

데이터베이스 객체에 걸리는게 아닌 사용자가 지정한 문자열에 대해 획득하고 반납하는 잠금.

많은 레코드를 한번에 변경하는 트랜잭션의 경우 유용하다 배치성 프로그램의 경우 데드락의 원인이 되곤 하는데 이때 유저락을 걸면 간단히 해결될 수 있다고...?


네임 락

데이터베이스 객체의 이름을 변경시 획득하는 락. 이름을 변경할때 묵시적으로 획득.


innoDB는 레코드 기반의 잠금을 지원. 하지만 어떤식으로 트랜잭션이 이루어지는 지 알기가 좀 힘듬

5.1 부터 information_schema 데이터베이스 안에 INNODB_TRX, INNODB_LOCKS, INNODB_LOCK_WAIT 테이블을 조인하여 조회하면 어떤 트랜잭션이 어떤 잠금을 대기하고 있고 해당 잠금을 어느 트랜잭션이 가지고 있는지 확인할 수 있다.

장시간 잠금상태인 클라이언트를 종료시킬 수도 있다.



Optimistic locking

각 트랜잭션이 같은 레코드를 변경할 가능성은 희박할 것이라고 가정.

우선 변경하고 마지막에 잠금 충돌이 있었는지 확인하고 문제가 있다면 롤백한다.


Pessimistic locking

현 트랜잭션에서 변경하고자 하는 레코드에 잠금을 획득하고 변경작업을 처리.

이 레코드를 다른 트랜잭션에서도 변경할 수 있다는 비관적 가정으로 먼저 락을 획득.

일반적으로 높은 동시성 처리에는 비관적 잠금이 유리하다고 알려져 있다.


innoDB의 락

레코드락, 레코드만을 잠그는 락. 하지만 이노디비 엔진은 인덱스 레코드를 잠근다.


갭락

레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 것. 레코드 사이에 새로운 레코드가 생성되는 것을 제어. 자체적으로 사용하진 않음.


넥스트 키 락

statement 바이너리 로그를 사용시엔 repeatable read 격리수준 사용 필요.

innodb_locks_unsafe_for_binlog 파라미터가 비활성화시 넥스트 키 락 방식으로 락이 걸림.

바이너리 로그에 기록되는 쿼리가 슬레이브에서 실행될 때 마스터에서 만들어 낸 결과와 동일한 결과를 만들어내도록 보장하는 것이 주 목적.

의외로 갭락과 넥스트키락으로 인해 데드락이 발생하는 경우가 많다.


자동 증가 락 auto increment lock

auto_increent컬럼 속성이 상ㅇ되었을때 발생하는 테이블 수준의 락

insert, replcae의 경우에만 필요.

명시적으로 획득할 순 없음.

5.1 부턴 방식 설정이 가능

연속(Consecutive mode)모드 대량 삽입시 한번에 여러개의 자동증가 값을 할당 받아서 사용. 이경우 중간에 누락되는 값이 발생함.

적어도 최소한 하나의 삽입 문장으로 삽입되는 레코드는 연속된 자동증가 값을 가져서 연속모드라고...


인터리빙 모드

유니크함 만 보장. 락을 걸지않음. 처리성능은 향상되나 복제시 마스터와 슬레이브의 자동증가 값이 달라질 수 있음.


innoDb의 레코드 락

인덱스 레코드락. 1개 컬럼에 인덱스가 되어있고 해당 컬림의 값이 A인게 30개 있다면 A수정시 30개 레코드가 락이 걸림

인덱스가 없으면 풀스캔으로모든 레코드가 잠김


Read Uncommitted

아직 커밋 되지 않은 데이터도 다른 트랜잭션이 읽어 갈수 있음. 롤백되면 없는 데이터를 읽는 더티리드가 발생.

데이터가 나타났다 사라졌다...


Read Committed

커밋 완료된 데이터만 다른 트랜잭션에서 조회가능. 가장 일반적. 더티리드가 없음

(언두 로그의 데이터를 읽어갈 순 있다)

논 리피터블 리드가 발생.= 하나의 트랜잭션 내에서 똑같은 select 쿼리 실행시 항상 같은 결과가 필요하다는 Repeatable Read를 위반

웹에서는 큰 문제가 없으나 하나의 트랜잭션 내에서 데이터를 여러번 읽고 변경하는 금전적인 경우 문제가 될 수 있다.


Repeatable Read

바이너리 로그 사용시 최소 격리 수준

MVCC를 위해 언두영역에 백업된 이전 데이터를 이용해 동일 트랜잭션 내에서는 동일한 결과를 보여준다.

이를 위해 이 격리 수준에서는 MVCC를 보장하기위해 실행중인 트랜잭션 가운데 가장 오래된 트랜잭션 번호보다 트랜잭션 번호가 앞선 언두 영역의 데이터는 삭제 할 수 없다.

이 수준에서는 장시간 하나의 트랜잭션이 종료되지 않으면 언두 영역의 백업 데이터가 무한정 커질 수 있다

Select for Update로 조회시 중간에 다른 트랜잭션의 업데이트한 내용이 보일 수 있음. 이처럼 다른 트랜잭션에서 수행한 변경 작업에 의해 레코드가 보였다 안보였다 하는걸 팬텀 리드 라고 함.

select for update - select 하는 테이블에 쓰기 잠금을 거는 것.


Serializable

가장 엄격한 트랜잭션. 읽기도 모두 잠금을 획득해야 한다. 읽기 잠금시 다른 트랜잭션에서 레코드를 변경할 수 없다.



갭락과 넥스트 키락


https://idea-sketch.tistory.com/46




https://12bme.tistory.com/138

https://idea-sketch.tistory.com/45


'DATABASE' 카테고리의 다른 글

데드락  (0) 2018.12.22
DB MySQL을 중심으로(innoDB엔진)  (0) 2018.12.13
[DB & JSP] 각 Database 별 커넥션 풀 설정(계속 업데이트)  (0) 2011.11.08
Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

Groovy/gradle2014.09.11 21:46


gradle을 이용하여 의존성 관리 스크립트를 짜면

보통 다음과 같은 형태의 스크립트로 구성한다.

apply plugin: 'java' repositories { mavenCentral() } dependencies { compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final' testCompile group: 'junit', name: 'junit', version: '4.+' }

출처 - gradle.org 문서의 Example 8.1


하지만 종종 위와 같은 형태가 아닌

repositories{} 와 dependencies{} 를 buildscript{} 로 감싸는 경우가 있다.

import org.apache.commons.codec.binary.Base64

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
    }
}

task encode << {
    def byte[] encodedString = new Base64().encode('hello world\n'.getBytes())
    println new String(encodedString)
}

출처 - gradle.org 문서의 Example 60.7


위의 코드를 보면

외부 라이브러리 의존관계 설정에 compile, 이나 testCompile 등이 아닌 classpath를 사용 하고 있다.


어떤차이가 있을까?

전자의 경우엔 명시된 상황에서만 의존 라이브러리를 참조 할 수 있다.

즉 compile 로 명시된 라이브러리의 경우 자바 컴파일 시에 라이브러리를 참조한다는 이야기이다.(이때는 testCompile의 라이브러리를 참조하지 않는다.)

위 의존관계에 대한 자세한사항은 다음을 참조

http://www.gradle.org/docs/current/userguide/java_plugin.html#tab:configurations


이번엔 후자를 보자.

gradle을 사용할 때 task를 많이 사용 하게 될 것이다. 그리고 종종 스크립트 안에서 바로 외부 라이브러리의 특정 메소드를 사용해야 하는 경우가 있다. 그럴 경우 후자처럼 코드를 작성해야 한다.

예제에서는 apache commn codec 라이브러리의 Base64.encode() 메소드를 사용하기 위한 방법을 보여준다.

즉 후자와 같은 경우는 gradle의 스크립트에서 바로 외부 라이브러리를 참조해야 할 경우에 사용하는 방법이다.



참고자료

http://www.gradle.org/docs/current/userguide/organizing_build_logic.html#sec:external_dependencies

http://stackoverflow.com/questions/13923766/gradle-buildscript-dependencies

http://chimera.labs.oreilly.com/books/1234000001741/ch04.html#_buildscript_dependencies

'Groovy > gradle' 카테고리의 다른 글

[gradle] buildscript dependencies 와 dependencies 의 차이  (0) 2014.09.11
Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

JAVA2014.07.24 21:50

checked Exception & unchecked Exception

checked Exception

컴파일러 수준에서 인지할 수 있는 예외

try{}catch(){} 의 사용을 강제

 

unchecked Exception

runtimeException을 상속한 모든 Exception

Runtime(실행시)에 인지 할 수 있는 예외

try{}catch(){}문이 선택적

예외 처리의 유의 사항

이펙티브 자바에서 제시하는 예외처리의 유의점은 다음과 같다(항목 57 ~ 65)

항목. 57 - 예외 상황에서만 예외를 사용하자

다음과 같은 코드는 작성하면 안된다

try {
    int i = 0;
    while(true)
       range[i++].climb();
} catch(ArrayIndexOutOfBoundsException e) {       
}

항목. 58 - 복구 가능 상황에는 checked 예외를 사용하고 런타임 예외는 프로그램 예외에 사용하자

즉 해당 메소드를 호출한 곳에서 try ~ catch문을 이용하여 예외를 복구 할 수 있는 상황에만 사용되는 예외만을 checked 예외를 사용한다.

항목. 59 - checked 예외의 불필요한 사용을 피하자

항목. 60 - 표준 예외를 사용하자

항목. 61 - 하위 계층의 예외 처리를 신중하게 하자

무작정 상위계층으로 에러를 던지지 말자, 상위 계층으로 예외를 던질때는 상위계층이 알아 볼 수 있는 예외로 변환하여 던져야 한다.

항목. 62 - 메소드가 던지는 모든 예외를 문서하 하자

항목. 63 - 실패 상황 정보를 상세 메시지에 포함하자

항목. 64 - 실패 원자성을 갖도록 노력하자

호출된 메소드가 실행에 실패하더라도 객체 상태는 메소드 호출 전과 같아야 한다.

항목. 65 - 예외를 묵살하지 말자

다음과 같은 예외처리가 예외 묵살의 좋은 예이다.

try {
    ....
} catch(someException e) {}
 try {
    ....
} catch(someException e) {
    e.printStatckTrace();
}

Checked Exceptoin의 문제점

코드가 너무 많이 생긴다

깨지기 쉬운 메소드 원형

끝없는 예외 wrapping

checked exceptoin이 인터페이스에서 잘 동작하지 않는다

http://bleujin.tistory.com/30

 

checked Exception은 OCP(개방 폐쇄 원칙)을 위반한다

http://cleancodes.tistory.com/5

어떤 때 예외 처리를 해야 하는가?

이 글을 쓰게 된 취지는 이 의문에 대한 답을 찾아보기 위함이었다.

하지만 예외 처리 관련하여 자료를 찾고 공부를 할 수록 이에 대한 '명확한 답은 없다' 는 점만 더 확실해 졌다.

 

결론적으로, 예외처리는 개발자가 알아서 판단하여야 한다.

 

그래도 개인적으로 다음과 같은 가이드라인 정도는 제시할 수 있지 않을까 생각한다.

예외가 발생하는 상황이라면 예외가 발생하여야 한다.

예외가 발생한다는건 코드의 문제이건, 외부 요인의 문제이건 어떠한 문제가 존재한다는 이야기 이다.

그렇다면 예외 발생하였음을 인지해야 문제를 고치고 넘어가지, 예외가 발생했는데도 마치 프로그램이 멀쩡히 돌아가는 것 처럼 보여선 안된다. (대표적으로 항목 65 - 예외 묵살하기)

여러 예외가 발생하였는데도 모르고 그냥 지나가 버리면 오히려 더 큰 문제를 발생시키기위한 요인이 되어 버린다.

 

외부 요인으로 인한 예외가 발생하는 경우

예를 들어 외부 서버와의 통신을 하는 sdk 제공받아 개발을 진행중이라고 가정하자.

사용하는 메소드 중

coupang.getCoupangUserList(args1, args2);

같은 것이 있고, 위 메소드가 외부 서버와 통신을 하여 데이터를 가져온다면, 인터넷 환경등의 문제로 연결이 끊기는 등의 문제가 발생할때를 대비하여 

몇초이상 응답이 없을 경우 TimeOutException 등을 던지도록 개발되었을 것이다.

이런 경우는 필히 사용자가 상황을 인지해야하고, 또한 예외로 인한 프로그램다운등을 막기 위하여 

try ~ catch 등을 이용하여 예외처리를 해 주어야 할 것이다.

 

비지니스 로직 상에서 발생하여 사용자에게 인지시킬 필요가 있는 경우

간단한 예로 회원가입 등의 경우 필수 파라미터가 있다.

이런것들이 어떠한 이유로 누락되거나, 엉뚱한 값이 넘어오거나 했을 때 예외를 발생시키고 이를 사용자가 인지할 수 있도록 예외처리를 할 수 있다.

 

그외 개발자 판단하에 필요하다 싶은 부분에 예외 처리 로직을 작성한다.

참고자료

http://www.nextree.co.kr/p3239/

http://blog.benelog.net/1901121

http://homo-ware.tistory.com/161

http://b4you.net/blog/tag/Unchecked%20Exception

http://slipp.net/questions/259

http://kwonnam.pe.kr/wiki/java/exception?s[]=checked&s[]=exception

Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

개발툴...2014.06.09 22:00

3. SourceTree 를 이용한 Pull & Merge


Git에는 Fetch와 Pull이 있습니다. 이 둘은 조금다른데 공식[?] 설명은 Fetch는 원격서버의 정보를 가져오지만 merge를 하지 않고, Pull은 정보를 가져와서 merge를 한다 라고 되어 있습니다.


쉽게 말해 Fetch는 원격서버의 정보를 새로고침 하는 것이고 Pull은 원격서버 정보를 로컬에 반영하는 것 입니다.


스샷을 봅시다.

지난화 마지막에서 파일 하나를 수정한 후 커밋한 모습입니다. 원격서버는 다른 브랜치를 가리키고 있습니다.

우선 변경점을 원격에 푸시하기전에 먼저 페치를 해 봅시다.(중간의 Fetch 아이콘을 누릅시다. 점화살표)


무언가 변화가 생겼습니다. Pull에 1 아이콘이 생기고 Push에도 1 아이콘이 생겼네요(빨간박스)

깃 로그도 무언가 달라졌습니다. 트리그래프도 분기가 되었습니다.


이는 다른 누군가가 서버에 푸시를 해놓았단 이야기 입니다. 원격 서버에 변경이 일어났다는 것이죠.

이런 상황에서는 Pull을 해서 로컬의 파일을 원격 파일들과 싱크를 맞춰주기 전에는 푸시가 불가능 합니다.

자 Pull을 눌러 이제 변경된 사항을 로컬에 반영하도록 합시다.


무언가 심각한 것 같은 상황이 보입니다(빨간박스)

이는 Conflict가 생겼다는 표시인데요. 동일 파일의 동일 라인을 나도 수정하고, 다른 사람도 수정했다는 소리입니다.

같은 곳을 건들였으니 충돌이 일어난 것이죠.  직접 파일에 가 확인해봅시다



꺽쇄와 = 표시로 충돌난 부분이 잘 나와 있습니다.

======= 윗부분의 HEAD 까지가 현 로컬에 작성되어 있는 부분이고

밑부분의 커밋 해시 값 까지가 원격에서 가져온 코드 입니다.


여기서 원하는걸 선택하고 버릴걸 지운후 기존에 Commit 하듯이 합시다.


화살표로 눌러 Staged Changes 로 올리면 변경되었단 표시가 나오고...


커밋을 하면 위와같이 소스트리에서 자동으로 생성한 커밋메세지가 들어가 있습니다.

팀의 컨벤션이나, 취향에 따라 커밋메세지를 바꾸시면 됩니다. (안바꿔도 되구요)

그리고 커밋을 완료합시다.


자 이제 서버로부터 Pull도 하였고 충돌도 해결하고 Merge도 완료되었습니다.

즉 원격서버의 변경점이 내가 사용하는 로컬에 merge되었습니다


그럼 로컬에선 2가지 변경점이 생겼습니다. 내가 본래 커밋한 것 하나, 원격의 변경점을 머지 한 것 하나.

빨간박스를 확인하면 푸시 버튼에 2가 표시된걸 보실 수 있습니다.



Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

개발툴...2014.06.08 23:11

소스트리 사용법 소개 두번째 시간입니다.

간단한건데 매우 오랜만에 올리네요 ㅠㅠ


2. SourceTree 를 이용한 Commit & Push

소스트리를 이용해서 커밋과 푸시를 진행하는 방법을 스샷을 보면서 간략하게 소개하겠습니다.


우선 프로젝트에서 파일을 변경후 세이브를 합니다.(예시로 간단하게 파일 하나반 면경하였습니다)


그리고 소스트리를 틀어보면 아래와 같은 화면이 나옵니다.


파란박스에는 커밋되지 않은 변경점이 있다고(영어로 쓰인)부분이 보이시죠?

그리고 녹색박스를 보면 정확히 어떤 파일이 바귀었는지 나옵니다. 지금은 파일 하나만 변경하여 하나만 보입니다.(우측엔 상세 변경내역이 표시 됩니다)

이전에 깃에 대해 설명할때, 깃은 커밋 직전 staging 이라는 한단계를 더 거친다고 했습니다.


현재는 파일이 변경된 상태일 뿐입니다.

빨간박스에 보이는 화살표를 눌러 stage 상태를 만들어 줘야 커밋이 가능해 집니다.

아래와 같이요.



staged changes에 파일이 올라간게 확인되면 좌측 상단 두번째 아이콘 Commit을 눌러줍니다.



그럼 위와 같은 화면이 보입니다.(사실 파일을 stage 공간에 넣는 작업을 여기서 해도 됩니다.)

커밋되는 파일은 Staged Changes에 보이는 파일만이 커밋이 됩니다. 즉 일부 파일은 커밋하기 싫다면 Working Copy Changes에 그대로 두거나, 다시 돌려보내도 된다는 소리이지요.


그리고 우측 하단의 커밋 버튼을 누르기전에 꼭 커밋 메세지(빨간박스)를 작성해야 합니다.

작성하였다면 커밋을 누릅시다.




커밋이 완료된 상황입니다.

깃 히스토리를 보여주는 화면에서 uncomminted changes가 사라지고 새로운 커밋이 하나 타나났습니다.(파란박스)

보시면 1ahead란 아이콘과 두개의 master 아이콘이 보이실 겁니다.

이는 원격 저장소와 몇개의 커밋이 차이가 있는지 를 보여주는 것 입니다.


그리고 현재 변경된건 로컬뿐이죠?

그렇기에 로컬의 master헤드는 새로운 커밋을 가르키고 있고, 아직 변경점이 반영이 안된 원격 저장소의 헤드(origin/master)는 이전 커밋을 가르키고 있습니다.


이제 원격저장소에도 변경점을 저장하기 위해 푸시를 해야 합니다. 푸시 버튼을 누릅시다.(빨간박스)




그럼 위처럼 로컬 브랜치와 그와 연결된 마스터 프랜치의 리스트가 나옵니다.

지금은 다 한개밖에 없어서 하나밖에 안나오지만요.

왼쪽에서 푸시할 로컬 브랜치를 선택하고, 오른쪽엔 푸시받을 원격저장소의 브랜치를 선택합니다. 즉, 로컬 브랜치 명이 마스터라도 원격의 다른 브랜치에 푸시할 수도 있습니다.


선택 완료 후 ok 를 눌러주면 프로그레스바가 뜨고, 인증이 필요하면 인증창도 뜨고 합니다.




에러 없이 완료되었다면 이 화면을 보실 수 있습니다.

원격의 origin/master와 로컬의 master가 같은 커밋을 가리키고 있는 것이 보이시죠?


이렇게 변경점의 커밋과 푸시가 완료되었습니다.




Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

OS/Linux2014.05.16 16:49

http://devday.tistory.com/entry/%EC%9E%90%EB%B0%94-Java%EC%97%90%EC%84%9C-GC-Garbage-Collection-%EB%A1%9C%EA%B7%B8-Log-%EB%82%A8%EA%B8%B0%EA%B8%B0



Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

개발툴...2014.05.11 20:58

Git GUI 도구인 소스트리에 대한 소개와, 소스트리를 이용해서 깃을 이용하는 방법을 소개합니다.

소스트리에 대해서는 사용하는 사람마다 호불호가 많이 갈리지만 전 이쁜[?] GUI로 인해서 좋아하는 편입니다.


소스트리 다운로드 사이트

http://www.sourcetreeapp.com/


소스트리는 위 사이트에서 받아서 설치하시면 됩니다.

설치는 정말 받아서 설치하면 끝납니다



1. 깃 저장소 연동하기 (GitHub 이용)

깃허브의 깃 저장소와 소스트리를 연동하는 예제를 먼저 진행합니다.


소스트리 설치가 끝났으면 실행을 합니다.


실행시 다음화면이 나오는데 여기서는 Mecurial을 사용하지 않을 것이기에 맨 아래

I don't want to Mecurial 을 눌러주세요

짚고가기 : Git 과 Mecurial



그리고 깃에서 사용할 사용자 정보를 입력합니다.

만일 git config 명령을 이용하여 글로벌 설정을 해 두었다면 자동으로 입력됩니다.




그 외의 설정들은 입맛에 맞는대로 쭉쭉 지나가시면 됩니다. 잘 모르겠으면 스킵해도 무방합니다.

아래의 여러 깃 저장소들의 계정을 입력하지 않아도 상관 없습니다.



위의 기본적인 설정을 마치고 나면 아래와 같은 화면이 나타납니다.

이제 깃 저장소와 연동, 정확히는 깃 저장소에서 소스코드를 클론해 오기위하여 아래의 빨간 박스(Clone / New) 를 클릭합니다.



그럼 아래와 같은 새 창이 뜹니다.

두번째 탭은 이미 있는 저장소를 소스트리에 인식 시키는 것이고, 세번째는 아예 새로운 깃 로컬 저장소를 만드는 것 입니다.

여기서는 GitHub 의 코드를 클론 하는 것이기에 첫번째 탭을 이용합니다.


Source Path 에는 깃헙 저장소 주소를 넣고

ex> https://github.com/{id}/{storageName}.git

Destination Path 에는 소스를 저장한 자신의 컴퓨터 경로를 입력합니다.




자 이제 Clone을 누르면 소스코드를 복사하는 프로그레스 바가 보여지고, 문제가 없다면 다음과 같은 화면이 뜨면서 소스트리를 이용하여 깃 원격저장소와 로컬 저장소의 연동이 끝나게 됩니다.



부가적으로 위 하면에 대해 설명하겠습니다.

빨간 박스 : 자신이 생성한 깃 저장소에 대한 북마크 목록이 나타납니다.

파란 박스 : 파일의 상태, 브랜치목록, 태그, 원격 저장소 등 현 저장소의 정보가 나타납니다.

녹색 박스 : 커밋 로그입니다. 간단한 메세지와 각 HEAD가 어딜 바라보고 있는지 등이 나타나며 TreeGrapth가 보여집니다. 위 예제는 첫 커밋밖에 없는 지라 그래프가 보이지는 않습니다.

노랑 박스 : 선택된 커밋에 대한 자세한 커밋로그, 변경된 파일과 변경된 소스코드들이 상세하게 나타납니다.


소스트리를 이용하여 깃을 다루기위한 기본 상태[?]는 이것으로 마치고, 이제 포스팅을 하나하나 추가하며 사용법을 작성하도록 하겠습니다.




Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

javascript2014.04.08 19:51


이전 포스팅인 [HTML] HTML Attribute와 javascript Property 에서 HTML Attribute 와 javascript의 Property에 대해 좀더 제대로 정리를 하기위해 남깁니다.


우선 w3school 에서 얻을 수 있는 HTML Attribute에 대한 설명은 다음과 같습니다.

HTML Attributes
HTML elements can have attributes
Attributes provide additional information about an element
Attributes are always specified in the start tag
Attributes come in name/value pairs like: name="value"

- attributes(속성) 는 elements(요소) 에 포함 되는 것
- element 에 대한 추가적인 정보를 제공한다
- attribute는 항상 시작tag 에 저장되어 있다.
- attribute는 name = "value" 의 형태로 나타난다.

JavaScript Properties
Properties are the values associated with a JavaScript object.
A JavaScript object is a collection of unordered properties.
Properties can usually be changed, added, and deleted, but some are read only.

property는 javascript object와 연관되어진 값들 입니다.
javascript object는 정렬되지 않은 property 의 콜렉션 입니다.
property는 바뀔 수 있고, 추가되고 지워질 수 있습니다. 단 어떤 것은 읽기만이 가능 합니다.

property는 코드를 보며 이해하는게 좀더 명확 할텐데요.
자바스크립트의 object는 다음과 같은 형태를 가지고 있습니다.

var foo = function() {
    this.name = "hello";
}

위의 코드에서 foo 는 javascript object 이며 name 이 property 가 됩니다.
즉, property는 javascript object 에서 key="value" 형태로 구성된 것들 입니다.

요약하자면, attribute는 html element의 정보를, property는 자바스크립트 object의 정보들을 가져온다고 이해하면 될 듯 합니다.


이제 jQuery의 .attr()과 .prop()의 차이를 더 명확히 알 수 있을 것 같습니다.
.attr()은 HTML element의 정보를 기술하는 것들(name, value, class 등등)의 값을 가져오는 것입니다.

.prop()는 설명이 길어지는데...
HTML element들은 DOM 으로 표현되어 집니다. 그리고 이 DOM 은 javascript 를 이용하여 핸들링이 가능합니다.
이는 하나의 DOM object를 javascript 에서 마치 javascript object로 취급이 가능하다는 이야기 입니다.
실제로 document.getElementById 메소드를 이용하여 가져온 DOM object를 typeof 연산자를 사용해 보면 "object"를 반환합니다.
그리고 위에서 보았듯이 이 object는 key="value" 형태를 띈 property들로 구성되어 집니다.
여기서 .prop() key의 값, value를 가져오는 것입니다.

요약하면 DOM object의 property 값을 가져온다고 할 수 있겠습니다.

다음은 이와 관련하여 추가적으로 이해하면 좋을 내용들에 대한 링크 입니다.

The DOM and JavaScript


ps. 잘못되거나 추가해야될 내용등에 대한 지적은 언제나 환영합니다.


Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

javascript/jQuery2014.03.18 17:27

현재 jQuery버전은 2.1.0 등이 릴리즈 되고 있는 상황이지만... 한번 정리를 하고 넘어가고자 글을 남깁니다.


jQuery 1.6 부터 .prop() 메소드가 추가되었습니다.

즉 본래 다른 속성인 attribute와 property를 .attr() 메소드로 가져오던 것을 1.6부터는 구분하기 시작했습니다.


그럼 .attr()과 .prop()는 어떻게 다를까요?

.attr()은 attribute 정보를, .prop()는 property 정보를 가져 옵니다.

즉 먼저 attribute와 property 의 차이를 알아야 하는데요.

명확하게 설명하기가 힘들지만 설며을 하자면 (더 명확한 설명을 아시는분 꼭 이야기 해 주세요)


attrubute는 HTML Element 의 속성들을 뜻하며

property는 자바스크립트의..... (마땅히 번역할 말을 모르겠으니 그냥 프로퍼티로 하겠습니다)

자바스크립트의 프로퍼티를 뜻합니다.


즉 attribute는 HTML Element에서 사용되고, property는 자바스크립트에서 사용되는 정보라고 보시면 됩니다.

이 둘은 비슷한거 같지만 생각보다 굉장히 큰 차이를 가지고 있습니다.


jQuery 사이트에 올라와 있는 차이를 본다면...


Attributes vs. Properties

The difference between attributes and properties can be important in specific situations. Before jQuery 1.6, the .attr()method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior. As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.

For example, selectedIndextagNamenodeNamenodeTypeownerDocumentdefaultChecked, and defaultSelected should be retrieved and set with the .prop() method. Prior to jQuery 1.6, these properties were retrievable with the .attr() method, but this was not within the scope of attr. These do not have corresponding attributes and are only properties.

Concerning boolean attributes, consider a DOM element defined by the HTML markup <input type="checkbox" checked="checked" />, and assume it is in a JavaScript variable named elem:

elem.checkedtrue (Boolean) Will change with checkbox state
$( elem ).prop( "checked" )true (Boolean) Will change with checkbox state
elem.getAttribute( "checked" )"checked" (String) Initial state of the checkbox; does not change
$( elem ).attr( "checked" )  (1.6)"checked" (String) Initial state of the checkbox; does not change
$( elem ).attr( "checked" ) 
(1.6.1+)
"checked" (String) Will change with checkbox state
$( elem ).attr( "checked" )  (pre-1.6)true (Boolean) Changed with checkbox state


According to the W3C forms specification, the checked attribute is a boolean attribute, which means the corresponding property is true if the attribute is present at all—even if, for example, the attribute has no value or is set to empty string value or even "false". This is true of all boolean attributes.

Nevertheless, the most important concept to remember about the checked attribute is that it does not correspond to the checked property. The attribute actually corresponds to the defaultChecked property and should be used only to set theinitial value of the checkbox. The checked attribute value does not change with the state of the checkbox, while the checkedproperty does. Therefore, the cross-browser-compatible way to determine if a checkbox is checked is to use the property:

  • if ( elem.checked )
  • if ( $( elem ).prop( "checked" ) )
  • if ( $( elem ).is( ":checked" ) )

The same is true for other dynamic attributes, such as selected and value.


영어 해석은 힘드니 ㅠㅠ 주요 차이만 짚고 넘어가겠습니다.

확실히 보아야 할 부분은...


$( elem ).attr( "checked" ) (1.6)

$( elem ).attr( "checked" ) (1.6.1+)

$( elem ).prop( "checked" )


요 세가지 입니다.

보시는는 바와같이 .attr()을 사용 할 경우 "checked" 라는 스트링 값 이 넘어옵니다.

하지만 .prop()에선 체크박스의 체크 상태가 true, false 값으로 넘어옵니다.


정리하자면

.attr()을 사용할 경우, 해당 HTML attribute의 값이 모두 String으로 넘어오며, 

.prop()를 사용할 경우 자바스크립트의 프로퍼티값이 넘어오기에 boolean, date, 혹은 function 까지도 넘어 올 수 있습니다.



좀더 확실한 차이를 보자면, onclick, onchange등의 본래 자바스크립트 메소드들의 경우라면

onclick="someFunction()"  이라고 작성되었다고 볼때

.attr() 의 경우 "someFunction()" 이라는 스트링이

.prop() 의 경우onclick  펑션이 넘어오는걸 보실 수 있습니다.

(물론 요런 요상한 코드를 작성할 일이 있을진 모르겠지만...)



이상의 차이가 있으니 앞으로는 .attr()과 .prop()가 사용될 부분을 잘 구분하여 버그로인한 스트레스를 줄이도록 노력합시다~







Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

JAVA/Spring2014.02.20 22:28

해당 글에 사용된 토비의 스프링 3의 그림 및 소스 등에 대한 저작권은 이일민 님께 있습니다. 문제가 발생시 해당 글은 언제든지 내려질 수 있습니다.

해당 글은 이일민 님의 허락하에 작성되었습니다.

덧. 본인의 복습과 정리를 목적으로 작성하였기에 토비의 스프링을 읽지 않으셨다면 잘 안맞는 부분이 있을 수 있습니다.




토비의 스프링 2장은 테스트에 관한 이야기 입니다.


단위테스트

한가지의 관심에만 집중할 수 있도록 작성한 작은 단위의 테스트 코드.

개발자가 설계하고 만든 코드가 의도한 대로 작동하는지 개발자 스스로 빠르게 확인하기 위해 사용.


포괄적인 테스트

전반적인 기능의 동작을 모두 테스트하는 것이라 볼 수 있다.

예를 들어 Dao를 테스트 한다면 CRUD기능들과 예외발생 부분 등을 모두 검증 하는 것이다.



1장에선 초난감 Dao를 개선하였다면, 이번 장에서는 UserDaoTest라는 테스트케이스를 개선하는 작업이 이루어진다.

UserDaoTest 의 

기능

  • main() 메소드를 이용

  • 테스트할 대상인 UserDao의 오브젝트를 가져와 메소드를 호출

  • 테스트에 사용할 입력 값을 직접 코드에서 만듬

  • 테스트 결과를 콘솔에 출력

  • 각 단계가 에러없이 끝나면 콘솔에 성공메세지 출력

문제점

  • 수동 확인 작업의 번거로움

    • 일일히 실행하고 직접 확인하여야 함

  • 실행 작업의 번거로움

    • 테스트할 클래스가 많아질 수록 실행할것도 많아짐


UserDaoTest 개선하기

main() 메소드를 jUnit 메소드로 전환

  -> 수행 부담 감소

테스트 메소드 전환, jUnit 제공 메소들 검증코드 전환

  -> 코드 검증 자동화

사용자 정보가 없는 예외조건에 대한 테스트 

  -> 예외처리 검증

스프링 컨텍스트 사용을 위해 @RunWith, @ContextConfigration 어노테이션 사용 

  -> 스프링을 이용한 DI 가 가능해진다.

@before 어노테이션을 이용하여 초반에 항상 테이블을 초기화 해 줌으로써 동일한 결과의 보장

@Autowired 어노테이션을 이용하여 간편한 DI - 차후 설명

ApplicationContext는 자기 자신도 Spring Bean으로 만든다.

테스트를 위한 별도의 ApplicationContext 설정 파일 

  -> 실제 코드와 테스트 코드의 관리 용이 및 실수 방지(실서버 디비가 날라간다던가...)


jUnit ?

자바 개발자를 위한 테스팅 프레임워크


jUnit 이 테스트 클래스를 가져와 테스트를 수행하는 방식


  1. 테스트 클래스에서 @Test가 붙은 public void 형, 파라미터가 없는 테스트 메소드를 모두 찾는다.

  2. 테스트 클래스 오브젝트를 하나 만든다.

  3. @Before가 붙은 메소드가 있으면 실행

  4. @Test 가 붙은 메소드를 하나 호출하고 테스트 결과 저장

  5. @After 가 붙은 메솓가 있으면 실행

  6. 나머지 테스트 메소드에 대해 2~5번 반복

  7. 모든 결과를 종합하여 돌려줌



TIP

침투적 기술과 비 침투적 기술

침투적 기술은 기술을 적용 했을 때 코드에 기술관련 api가 등장하거나, 특정 인터페이스나 클래스를 사용하도록 강제하는 기술.

침투적 기술을 사용하면 코드가 해당 기술에 종속되는 결과를 가져온다.

비침투적 기술은 어플리케이션 로직을 담은 코드에 아무런 영향을 주지 않고 적용이 된다. 따라서 기술에 비 종속적인 순수한 코드를 유지할 수 있게 해준다. 스프링은 이런 비침투적 기술의 대표적인 예다.


동등분할(equivalence partitioning)

같은 결과를 내는 값의 범위를 구분해서 각 대표 값으로 테스트를 하는 방법. 어떤 작업 결과가 총 세가지라면(true, false, exception) 각 결과를 내는 입력 값이나 상황에 따른 조합을 만들어 모든 경우에 대한 테스트를 하는 것이 좋다.


경계값 분석(boundary value analysis)

에러는 동등분할 범위의 경계에서 주로 발생하는 특징을 이용하여 경계의 근처에 대한 값을 이용해 테스트 하는 방법. 숫자의 경우 0이나 그 주변 값, 혹은 정수의 최대값 최소값 등으로 테스트를 하면 도움이 된다.




샘플 코드

https://github.com/maximinhan/mytobyspring3/tree/master/spring02


'JAVA > Spring' 카테고리의 다른 글

[spring] 2. 테스트  (0) 2014.02.20
[Spring] 1. 오브젝트와 의존관계  (0) 2013.10.17
[Spring] 스프링 정리 시작합니다.  (0) 2013.10.17
Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

개발툴...2014.02.14 17:52

Selenium WebDriver에 관련된 정리 글들


셀레니움 - http://docs.seleniumhq.org/


솔웅님의 셀레니움관련 글 - http://coronasdk.tistory.com/727


셀레니움을 이용한 웹 어플리케이션 테스트 프로세스 - http://www.nextree.co.kr/selenium%EC%9D%84-%ED%99%9C%EC%9A%A9%ED%95%9C-%EC%9B%B9%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EC%8B%9C%ED%97%98/


[구루비] 셀레니움을 이용한 UI 테스트 - http://wiki.gurubee.net/pages/viewpage.action?pageId=6259762



Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요

개발툴...2014.02.06 11:03

쭈욱 읽어보니 소스트리등의 Git GUI툴이나

이클립스, 인텔리j의 Git 플러그인에서의 머지는 Commit Merge를 기본으로 하고 있다.

Fast-Froward Merge를 위해선 따로 체크를 해주어야 한다.


Git의 Merge 정책을 세울때 참고하면 꽤 좋은글.



http://dogfeet.github.io/articles/2011/git-merge.html



Posted by 하품 - yawn 하품 - yawn

댓글을 달아 주세요