DAO 고도화, 트랜잭션 관리

2024. 10. 18. 16:53·DB

DAO 고도화

DAO 고도화를 할 때, 먼저 개선해야 할 부분은 코드 중복이다. 특히 Ctrl+C+V로 반복해서 붙여넣는 부분이 많다면, 템플릿 패턴을 적용하는 것이 효과적이다.

 

템플릿 패턴

템플릿 패턴이란, 어떤 작업을 처리하는 일부분을 서브 클래스로 캡슐화해 전체 일을 수행하는 구조는 바꾸지 않으면서 특정 단계에서 수행하는 내역을 바꾸는 패턴이다. 

https://yn98.tistory.com/25 템플릿 패턴은 디자인패턴 중에서 행위 패턴 중 하나이다.

일반적으로 상위 클래스(추상 클래스)에는 추상 메서드를 통해 기능의 골격을 제공하고, 하위 클래스(구체 클래스)의 메서드에는 세부 처리를 구체화하는 방식으로 사용하며 코드 양을 줄이고 유지보수를 용이하게 만드는 특징을 갖는 디자인 패턴이다. 템플릿 패턴은 상위 작업의 구조를 바꾸지 않으면서 서브 클래스로 작업의 일부분을 수행한다.

 

 

템플릿 패턴은 반복되는 로직이나 복잡한 코드를 캡슐화해서 재사용할 수 있게 해주며, 성능 개선과 최적화에도 큰 도움이 된다. 특히 JDBC는 템플릿 패턴을 적용하기 좋은 대표적인 예시다.

 

템플릿 패턴 적용

JDBC에서 반복적으로 사용하는 데이터베이스 연결, 쿼리 실행, 자원 해제 등의 과정을 템플릿 패턴을 통해 간단하게 처리할 수 있다. 스프링이 제공하는 JDBCTemplate 클래스를 사용하면, 이러한 작업을 더 쉽게 처리할 수 있다. JDBCTemplate는 dataSource 객체에 의존하며, 커넥션 객체를 확보하고 해제하는 과정을 자동으로 관리해 준다.

 

Before - JDBCUtil.java

package com.yn.app.biz.common;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JDBCUtil {
	private static final String driverName="com.mysql.cj.jdbc.Driver";
	private static final String url="jdbc:mysql://localhost:3306/yena";
	private static final String userName="root";
	private static final String password="1234";
	
	public static Connection connect() {
		Connection conn=null;
		try {
			Class.forName(driverName);
		} catch (ClassNotFoundException e) {
			System.out.println("드라이버 로드 실패");
		}
		
		try {
			conn=DriverManager.getConnection(url, userName, password);
		} catch (SQLException e) {
			System.out.println("conn 연결 실패");
		}
		return conn;
	}
	
	public static void disconnect(PreparedStatement pstmt, Connection conn) {
		try {
			pstmt.close();
			conn.close();	
		} catch (SQLException e) {
			System.out.println("연결 해제 실패");
		}		
	}
}

After - applicationContext.xml

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
    <property name="username" value="root"/>
    <property name="password" value="1234"/>
</bean>

 

위와 같은 설정으로 dataSource 객체를 등록하면, JDBCTemplate에서 이를 이용해 데이터베이스와의 연결을 처리할 수 있다.

 

트랜잭션 관리

트랜잭션은 여러 기능을 하나의 단위로 묶어서 처리하는 개념이다.

예를 들어, 네이버 웹툰의 경우, 사용자가 1000원을 지불하고 쿠키를 구입해 웹툰을 보는 과정이 하나의 트랜잭션으로 묶일 수 있다. 만약 중간에 문제가 생겨서 웹툰을 보지 못하게 되면, 지불한 금액도 함께 취소되어야 한다. 이렇게 트랜잭션이 하나의 단위로 처리되는 것이 중요하다.

Spring에서는 tx:advice를 통해 트랜잭션을 쉽게 관리할 수 있다. 아래는 트랜잭션을 설정하는 기본 예시다.

<tx:advice transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

 

특히 select 작업은 데이터베이스의 변화를 일으키지 않기 때문에 read-only="true" 옵션을 설정해 성능을 최적화할 수 있다. 또한, 서비스가 실패했을 때 자동으로 롤백하는 기능을 통해 데이터의 일관성을 유지할 수 있다.

 

트랜잭션 예시

예시로 글 작성을 하는데, BID(== 글 PK)는 PK이므로 UNIQUE 한데 , 아래와 같이 코드를 작성한 후에, 글 작성을 하게 된다면,

@Override
	public boolean insert(BoardDTO boardDTO) {
		System.out.println("insert 01");
		boardDAO.insert(boardDTO); // 트랜잭션 처리 확인용 코드
		System.out.println("insert 02");
		return boardDAO.insert(boardDTO); // 하나의 서비스가 제대로 처리되지않아서, 서비스의 처음 상태로 되돌아감 == ROLLBACK
	}

 

위와 같은 에러를 만나게 된다.

더보기
더보기

심각: 경로 [/day058_hw]의 컨텍스트 내의 서블릿 [ds]을(를) 위한 Servlet.service() 호출이, 근본 원인(root cause)과 함께, 예외 [Request processing failed: org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT INTO BOARD (BID,CONTENT,WRITER) VALUES(?,?,?)]; Duplicate entry '20' for key 'board.PRIMARY']을(를) 발생시켰습니다.

java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '20' for key 'board.PRIMARY'

하나의 서비스가 제대로 처리되지않아서, 서비스의 처음 상태로 되돌아가게 된다. 이를 ROLLBACK이라고 한다.

여기서 서비스의 처음 상태란, 글 작성 전이다.

로그에 content= 111이다. 콘솔창 로그를 통해, content(내용)이 111이라는 글을 작성했다고 나오는데, 위 에러가 발생했기 때문에, ROLLBACK이 되어 아래와 같이 글이 추가가 안된 것을 알 수 있다.

내가 만든 간단한 게시판 페이지인데, 111이라는 내용은 찾을 수 없다.

 

조회를 해봐도, 새로 작성한 글 내용은 나오지 않는 것을 알 수 있다.

 

 

이와 같이 DAO를 고도화하고 트랜잭션을 적절히 관리함으로써,

더 효율적이고 안정적인 시스템을 구축할 수 있다.

'DB' 카테고리의 다른 글

[DBMS] 트리거, 이벤트 스케줄러  (1) 2024.11.14
[MyBatis] MyBatis 개념 및 구조  (1) 2024.11.04
[Oracle] DB 계정 생성 후 연동하기  (0) 2024.10.04
[DBMS] 정규화 정리  (0) 2024.08.12
SQL 기초  (1) 2024.06.15
'DB' 카테고리의 다른 글
  • [DBMS] 트리거, 이벤트 스케줄러
  • [MyBatis] MyBatis 개념 및 구조
  • [Oracle] DB 계정 생성 후 연동하기
  • [DBMS] 정규화 정리
yn98
yn98
좌우명 : 여전할 것 인가, 역전할 것 인가? 백엔드 개발자가 되고싶은 역전하고 있는 개발자 꿈나무의 블로그입니다. 개발을 하면서 공부한 것들을 기록합니다. 24.06 ~
  • yn98
    개발 꿈나무
    yn98
  • 전체
    오늘
    어제
    • 분류 전체보기 (131)
      • Python (3)
      • 공부 (7)
      • DB (7)
      • JAVA (24)
      • JSP (9)
      • jQuery (2)
      • HTML (3)
      • Spring (20)
      • 웹 (4)
      • C (1)
      • Git (2)
      • 에러일기 (19)
      • 프로젝트 (6)
      • 책 (21)
        • 멘토씨리즈 자바 (14)
        • 2024 수제비 정보처리기사 (7)
      • 기타 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
    • Notion
  • 공지사항

  • 인기 글

  • 태그

    티스토리챌린지
    어노테이션
    오버로딩
    aop
    객체지향
    html
    DispatcherServlet
    ViewResolver
    멘토씨리즈 자바
    jsp
    @Component
    수제비
    이벤트 스케줄러
    Spring
    2-layered 아키텍처
    스프링 프레임워크
    상속
    @service
    정처기
    오블완
    Di
    recoverabledataaccessexception
    정처기 실기
    @repository
    MVC
    정보처리기사
    정보처리기사 실기
    java
    생성자
    codeup 4891 : 행복
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
yn98
DAO 고도화, 트랜잭션 관리
상단으로

티스토리툴바