Spring/Spring DB

[μŠ€ν”„λ§ DB 1편] - 14. μŠ€ν”„λ§ μ˜ˆμ™Έ 처리

hello_u 2023. 3. 30. 11:25

 

체크 μ˜ˆμ™Έμ™€ μΈν„°νŽ˜μ΄μŠ€

 

μ„œλΉ„μŠ€ 계측은 가급적 νŠΉμ • κ΅¬ν˜„ κΈ°μˆ μ— μ˜μ‘΄ν•˜μ§€ μ•Šκ³ , μˆœμˆ˜ν•˜κ²Œ μœ μ§€ν•˜λŠ” 것이 μ’‹λ‹€.

 

μ΄λ ‡κ²Œ ν•˜λ €λ©΄ μ˜ˆμ™Έμ— λŒ€ν•œ μ˜μ‘΄λ„ ν•¨κ»˜ ν•΄κ²°ν•΄μ•Όν•œλ‹€.


예λ₯Ό λ“€μ–΄μ„œ μ„œλΉ„μŠ€κ°€ μ²˜λ¦¬ν•  수 μ—†λŠ” SQLException 에 λŒ€ν•œ μ˜μ‘΄μ„ μ œκ±°ν•˜λ €λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Όν• κΉŒ?

 

μ„œλΉ„μŠ€κ°€ μ²˜λ¦¬ν•  수 μ—†μœΌλ―€λ‘œ 리포지토리가 λ˜μ§€λŠ” SQLException 체크 μ˜ˆμ™Έλ₯Ό λŸ°νƒ€μž„ μ˜ˆμ™Έλ‘œ μ „ν™˜ν•΄μ„œ μ„œλΉ„μŠ€ 계측에 λ˜μ§€μž.

 

μ΄λ ‡κ²Œ ν•˜λ©΄ μ„œλΉ„μŠ€ 계측이 ν•΄λ‹Ή μ˜ˆμ™Έλ₯Ό λ¬΄μ‹œν•  수 있기 λ•Œλ¬Έμ—,

 

νŠΉμ • κ΅¬ν˜„ κΈ°μˆ μ— μ˜μ‘΄ν•˜λŠ” 뢀뢄을 μ œκ±°ν•˜κ³  μ„œλΉ„μŠ€ 계측을 μˆœμˆ˜ν•˜κ²Œ μœ μ§€ν•  수 μžˆλ‹€.

 

 

 

체크 μ˜ˆμ™Έ μ½”λ“œμ— μΈν„°νŽ˜μ΄μŠ€ λ„μž…

public class MemberRepositoryV3 implements MemberRepositoryEx {
    public Member save(Member member) throws SQLException {
        String sql = "insert into member(member_id, money) values(?, ?)";
    } }

 

μΈν„°νŽ˜μ΄μŠ€μ˜ κ΅¬ν˜„μ²΄κ°€ 체크 μ˜ˆμ™Έλ₯Ό λ˜μ§€λ €λ©΄, 

 

public interface MemberRepositoryEx {
    Member save(Member member) throws SQLException;
    Member findById(String memberId) throws SQLException;
    void update(String memberId, int money) throws SQLException;
    void delete(String memberId) throws SQLException;
}

 

μΈν„°νŽ˜μ΄μŠ€ λ©”μ„œλ“œμ— λ¨Όμ € 체크 μ˜ˆμ™Έλ₯Ό λ˜μ§€λŠ” 뢀뢄이 μ„ μ–Έ λ˜μ–΄ μžˆμ–΄μ•Ό ν•œλ‹€. 

 

κ·Έλž˜μ•Ό κ΅¬ν˜„ 클래슀의 λ©”μ„œλ“œλ„ 체크 μ˜ˆμ™Έλ₯Ό 던질 수 μžˆλ‹€.

 

ν•˜μ§€λ§Œ 이것은 μš°λ¦¬κ°€ μ›ν•˜λ˜ μˆœμˆ˜ν•œ μΈν„°νŽ˜μ΄μŠ€κ°€ μ•„λ‹ˆλ‹€. (SQLException - JDBC κΈ°μˆ μ— 쒅속적인 μΈν„°νŽ˜μ΄μŠ€)

 

ν–₯ν›„ JDBCκ°€ μ•„λ‹Œ λ‹€λ₯Έ 기술둜 λ³€κ²½ν•œλ‹€λ©΄ μΈν„°νŽ˜μ΄μŠ€ 자체λ₯Ό λ³€κ²½ν•΄μ•Ό ν•œλ‹€.

 

 

μΈν„°νŽ˜μ΄μŠ€μ— λŸ°νƒ€μž„ μ˜ˆμ™Έλ₯Ό λ”°λ‘œ μ„ μ–Έν•˜μ§€ μ•Šμ•„λ„ λ˜λŠ” λŸ°νƒ€μž„ μ˜ˆμ™Έλ₯Ό μ μš©ν•˜μž ! 

 

 

 

λŸ°νƒ€μž„ μ˜ˆμ™Έ 적용

 

public class MyDbException extends RuntimeException

 

RuntimeException 을 μƒμ†λ°›μ•˜λ‹€.

 

λ”°λΌμ„œ MyDbException 은 λŸ°νƒ€μž„(언체크) μ˜ˆμ™Έκ°€ λœλ‹€.

 

 

 MemberRepository μΈν„°νŽ˜μ΄μŠ€ 적용 

public class MemberRepositoryV4_1 implements MemberRepository
public Member save(Member member)

 

/**
*
μ˜ˆμ™Έ λˆ„μˆ˜ 문제 ν•΄κ²°
* 체크 μ˜ˆμ™Έλ₯Ό λŸ°νƒ€μž„ μ˜ˆμ™Έλ‘œ λ³€κ²½
* MemberRepository μΈν„°νŽ˜μ΄μŠ€ μ‚¬μš© * throws SQLException 제거
*/

 

catch (SQLException e) {
        throw new MyDbException(e);

κΈ°μ‘΄ 체크 μ˜ˆμ™ΈμΈ SQLException 을 RuntimeException 을 상속받은 MyDbException 으둜 λ³€ν™˜

 

κΈ°μ‘΄ μ˜ˆμ™Έλ₯Ό μƒμ„±μžλ₯Ό ν†΅ν•΄μ„œ ν¬ν•¨ν•˜κ³  μžˆλŠ” 것을 확인할 수 μžˆλ‹€.

 

κ·Έλž˜μ•Ό μ˜ˆμ™Έλ₯Ό 좜λ ₯ν–ˆμ„ λ•Œ 원인이 λ˜λŠ” κΈ°μ‘΄ μ˜ˆμ™Έλ„ ν•¨κ»˜ 확인할 수 μžˆλ‹€.

 

MyDbException 이 내뢀에 SQLException 을 ν¬ν•¨ν•˜κ³  μžˆλ‹€κ³  μ΄ν•΄ν•˜λ©΄ λœλ‹€.

 

μ˜ˆμ™Έλ₯Ό 좜λ ₯ν–ˆμ„ λ•Œ μŠ€νƒ 트레이슀λ₯Ό 톡해 λ‘˜λ‹€ 확인할 수 μžˆλ‹€.

 

μ˜ˆμ™Έλ₯Ό λ³€ν™˜ν•  λ•ŒλŠ” κΈ°μ‘΄ μ˜ˆμ™Έλ₯Ό κΌ­! ν¬ν•¨ν•˜μž.

 

 

정리

 

체크 μ˜ˆμ™Έλ₯Ό λŸ°νƒ€μž„ μ˜ˆμ™Έλ‘œ λ³€ν™˜ν•˜λ©΄μ„œ μΈν„°νŽ˜μ΄μŠ€μ™€ μ„œλΉ„μŠ€ κ³„μΈ΅μ˜ μˆœμˆ˜μ„±μ„ μœ μ§€ν•  수 있게 λ˜μ—ˆλ‹€.

 

덕뢄에 ν–₯ν›„ JDBCμ—μ„œ λ‹€λ₯Έ κ΅¬ν˜„ 기술둜 λ³€κ²½ν•˜λ”λΌλ„ μ„œλΉ„μŠ€ κ³„μΈ΅μ˜ μ½”λ“œλ₯Ό λ³€κ²½ν•˜μ§€ μ•Šκ³  μœ μ§€ν•  수 μžˆλ‹€.

 

 

 

데이터 μ ‘κ·Ό μ˜ˆμ™Έ 직접 λ§Œλ“€κΈ°

 

λ°μ΄ν„°λ² μ΄μŠ€ 였λ₯˜μ— λ”°λΌμ„œ νŠΉμ • μ˜ˆμ™ΈλŠ” λ³΅κ΅¬ν•˜κ³  싢을 수 μžˆλ‹€.


예λ₯Ό λ“€μ–΄μ„œ νšŒμ› κ°€μž…μ‹œ DB에 이미 같은 IDκ°€ 있으면 ID 뒀에 숫자λ₯Ό λΆ™μ—¬μ„œ μƒˆλ‘œμš΄ IDλ₯Ό λ§Œλ“€μ–΄μ•Ό ν•œλ‹€κ³  κ°€μ •ν•΄λ³΄μž.


ID
λ₯Ό hello 라고 κ°€μž… μ‹œλ„ ν–ˆλŠ”λ°, 이미 같은 아이디가 있으면 hello12345 와 같이 뒀에 μž„μ˜μ˜ 숫자λ₯Ό λΆ™μ—¬μ„œ κ°€μž…ν•˜λŠ” 것이닀.

 

 

λ°μ΄ν„°λ² μ΄μŠ€ 였λ₯˜ μ½”λ“œ

데이터λ₯Ό DB에 μ €μž₯ν•  λ•Œ 같은 IDκ°€ 이미 λ°μ΄ν„°λ² μ΄μŠ€μ— μ €μž₯λ˜μ–΄ μžˆλ‹€λ©΄, λ°μ΄ν„°λ² μ΄μŠ€λŠ” 였λ₯˜ μ½”λ“œλ₯Ό λ°˜ν™˜ν•˜κ³ ,

 

이 였λ₯˜ μ½”λ“œλ₯Ό 받은 JDBC λ“œλΌμ΄λ²„λŠ” SQLException 을 λ˜μ§„λ‹€.

 

그리고 SQLException μ—λŠ” λ°μ΄ν„°λ² μ΄μŠ€κ°€ μ œκ³΅ν•˜λŠ” errorCode λΌλŠ” 것이 λ“€μ–΄μžˆλ‹€.

 

SQLException 내뢀에 λ“€μ–΄μžˆλŠ” errorCode λ₯Ό ν™œμš©ν•˜λ©΄ λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ μ–΄λ–€ λ¬Έμ œκ°€ λ°œμƒν–ˆλŠ”μ§€ 확인할 수 μžˆλ‹€.

 

 

μ˜ˆμ™Έλ₯Ό ν™•μΈν•΄μ„œ λ³΅κ΅¬ν•˜λŠ” κ³Όμ •

 

μ„œλΉ„μŠ€ κ³„μΈ΅μ—μ„œλŠ” μ˜ˆμ™Έ 볡ꡬλ₯Ό μœ„ν•΄ ν‚€ 쀑볡 였λ₯˜λ₯Ό 확인할 수 μžˆμ–΄μ•Ό ν•œλ‹€.

 

κ·Έλž˜μ•Ό μƒˆλ‘œμš΄ IDλ₯Ό λ§Œλ“€μ–΄μ„œ λ‹€μ‹œ μ €μž₯을 μ‹œλ„ν•  수 있기 λ•Œλ¬Έμ΄λ‹€.

 

μ΄λŸ¬ν•œ 과정이 λ°”λ‘œ μ˜ˆμ™Έλ₯Ό ν™•μΈν•΄μ„œ λ³΅κ΅¬ν•˜λŠ” 과정이닀.

 

λ¦¬ν¬μ§€ν† λ¦¬λŠ” SQLException 을 μ„œλΉ„μŠ€ 계측에 λ˜μ§€κ³  μ„œλΉ„μŠ€ 계측은 이 μ˜ˆμ™Έμ˜ 였λ₯˜ μ½”λ“œλ₯Ό ν™•μΈν•΄μ„œ

 

ν‚€ 쀑볡 였λ₯˜( 23505 )인 경우 μƒˆλ‘œμš΄ IDλ₯Ό λ§Œλ“€μ–΄μ„œ λ‹€μ‹œ μ €μž₯ν•˜λ©΄ λœλ‹€.

 

 

그런데 SQLException 에 λ“€μ–΄μžˆλŠ” 였λ₯˜ μ½”λ“œλ₯Ό ν™œμš©ν•˜κΈ° μœ„ν•΄ SQLException 을 μ„œλΉ„μŠ€ κ³„μΈ΅μœΌλ‘œ λ˜μ§€κ²Œ 되면,

 

μ„œλΉ„μŠ€ 계측이 SQLException μ΄λΌλŠ” JDBC κΈ°μˆ μ— μ˜μ‘΄ν•˜κ²Œ λ˜λ©΄μ„œ, μ§€κΈˆκΉŒμ§€ μš°λ¦¬κ°€ κ³ λ―Όν–ˆλ˜ μ„œλΉ„μŠ€ κ³„μΈ΅μ˜ μˆœμˆ˜μ„±μ΄ λ¬΄λ„ˆμ§„λ‹€.

 

 

 

이 문제λ₯Ό ν•΄κ²°ν•˜λ €λ©΄ μ•žμ„œ 배운 것 처럼 λ¦¬ν¬μ§€ν† λ¦¬μ—μ„œ μ˜ˆμ™Έλ₯Ό λ³€ν™˜ν•΄μ„œ λ˜μ§€λ©΄ λœλ‹€.

 

 

SQLException -> MyDuplicateKeyException

public class MyDuplicateKeyException extends MyDbException

 

기쑴에 μ‚¬μš©ν–ˆλ˜ MyDbException(RuntimeException) 을 μƒμ†λ°›μ•„μ„œ μ˜λ―ΈμžˆλŠ” 계측을 ν˜•μ„±ν•œλ‹€.

 

μ΄λ ‡κ²Œν•˜λ©΄ λ°μ΄ν„°λ² μ΄μŠ€ κ΄€λ ¨ μ˜ˆμ™ΈλΌλŠ” 계측을 λ§Œλ“€ 수 μžˆλ‹€.


그리고 이름도 MyDuplicateKeyException μ΄λΌλŠ” 이름을 μ§€μ—ˆλ‹€.

 

이 μ˜ˆμ™ΈλŠ” 데이터 μ€‘λ³΅μ˜ κ²½μš°μ—λ§Œ λ˜μ Έμ•Ό ν•œλ‹€.

 

이 μ˜ˆμ™ΈλŠ” μš°λ¦¬κ°€ 직접 λ§Œλ“  것이기 λ•Œλ¬Έμ—, JDBCλ‚˜ JPA 같은 νŠΉμ • κΈ°μˆ μ— 쒅속적이지 μ•Šλ‹€.

 

λ”°λΌμ„œ 이 μ˜ˆμ™Έλ₯Ό μ‚¬μš©ν•˜λ”λΌλ„ μ„œλΉ„μŠ€ κ³„μΈ΅μ˜ μˆœμˆ˜μ„±μ„ μœ μ§€ν•  수 μžˆλ‹€.

(ν–₯ν›„ JDBCμ—μ„œ λ‹€λ₯Έ 기술둜 바꾸어도 이 μ˜ˆμ™ΈλŠ” κ·ΈλŒ€λ‘œ μœ μ§€ν•  수 μžˆλ‹€.)

 

 

 

 

 

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-db-1/dashboard

 

μŠ€ν”„λ§ DB 1편 - 데이터 μ ‘κ·Ό 핡심 원리 - μΈν”„λŸ° | κ°•μ˜

λ°±μ—”λ“œ κ°œλ°œμ— ν•„μš”ν•œ DB 데이터 μ ‘κ·Ό κΈ°μˆ μ„ κΈ°μ΄ˆλΆ€ν„° μ΄ν•΄ν•˜κ³ , μ™„μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μŠ€ν”„λ§ DB μ ‘κ·Ό 기술의 원리와 ꡬ쑰λ₯Ό μ΄ν•΄ν•˜κ³ , 더 κΉŠμ΄μžˆλŠ” λ°±μ—”λ“œ 개발자둜 μ„±μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€., - κ°•μ˜

www.inflearn.com