Per ardua ad astra !
I'm On My Way
Per ardua ad astra !
전체 방문자
오늘
어제
  • 분류 전체보기 (126)
    • Algorithm (50)
      • 백준 (30)
      • SWEA (3)
      • JUNGOL (3)
      • Programmers (5)
      • LeetCode (2)
    • 안드로이드 개발 (6)
      • Java로 개발 (0)
      • Kotlin으로 개발 (3)
    • Spring (41)
      • Spring기본 (17)
      • JPA기본 (15)
      • JPA활용 SpringBoot 기본 (9)
      • API 개발 기본 (0)
    • 네트워크 (3)
    • 운영체제 (0)
    • Life (3)
      • 책 (0)
      • 자기계발 (1)
      • 일상 (2)
    • 노마드코더 (3)
      • python으로 웹 스크래퍼 만들기 (3)
    • 프로그래밍 언어 (17)
      • Java 기본 (2)
      • 코틀린 기본 (15)

블로그 메뉴

  • 홈
  • 방명록

인기 글

hELLO · Designed By 정상우.
Per ardua ad astra !

I'm On My Way

Spring/Spring기본

Tansaction 처리

2021. 1. 16. 16:06

트렌젝션(Transaction)

DB의 상태를 변화시킬 수 있는 여러 쿼리를 논리적으로 하나의 작업으로 묶어주는 작업을 의미한다.   

 

롤백(RollBack)

쿼리 실행 결과를 취소하고 DB를 기존 상태로 되돌리는 것을 의미한다.

 

커밋(Commit)

트랜잭션으로 묶인 쿼리가 모든 작업을 성공적으로 수행해서 쿼리 결과를 실제 DB에 반영하는 것을 의미한다.

 

 

트렌젝션 설정을 통한 커밋과 롤백이 잘 출력되는지 확인하기 위해서는 Log메세지를 출력하도록 설정해야한다.

Logback을 사용해보자

 

Logback 사용

 

의존 추가

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.7.25</version>
		</dependency>
        	<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>1.2.3</version>
		</dependency>
        

 

pom.xml 파일에 이 의존을 추가한다.

 

 

Logback 설정파일 추가

<?xml version="1.0" encoding="UTF-8"?>

<configuration>
	<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>%d %5p %c{2} - %m%n</pattern>
		</encoder>
	</appender>
	<root level="INFO">
		<appender-ref ref="stdout" />
	</root>

	<logger name="org.springframework.jdbc" level="DEBUG" />
</configuration>

 

 

트렌젝션 설정

 

관련파일들을 우선 살펴보고 트렌젝션 적용 방법을 정리해보자. 

 

ChangePasswordService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package spring;
 
import org.springframework.transaction.annotation.Transactional;
 
public class ChangePasswordService {
    
    private MemberDao memberDao;
    
    @Transactional
    public void changePassword(String email, String oldPwd, String newPwd) {
        Member member = memberDao.selectByEmail(email);
        if(member == null                    )
            throw new MemberNotFoundException();
        
        member.changePassword(oldPwd, newPwd);
        memberDao.update(member);
    }
    
    public void setMemberDao(MemberDao memberDao) {
        this.memberDao = memberDao;
    }
}
 
Colored by Color Scripter
cs

 

AppCtx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package config;
 
import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
 
import spring.ChangePasswordService;
import spring.MemberDao;
 
@Configuration
@EnableTransactionManagement
public class AppCtx {
 
    private String driver = "com.mysql.cj.jdbc.Driver";
    private String url = "jdbc:mysql://127.0.0.1:3306/spring5fs?characterEncoding=UTF8&serverTimezone=UTC";
    private String url2 = "jdbc:mysql://localhost:3306/spring5fs?characterEncoding=UTF8&serverTimezone=UTC";
    
    private String username = "spring5";
    private String password = "spring5";
 
    @Bean(destroyMethod = "close")
    public DataSource dataSource()  {
        DataSource ds = new DataSource();
        ds.setDriverClassName(driver); // JDBC 드라이버 클래스 = MySQL 드라이버 클래스
        ds.setUrl(url); // JDBC URL을 지정
        ds.setUsername(username);
        ds.setPassword(password);
        // 커넥션 지정 메서드
        ds.setInitialSize(2); // 커넥션 풀을 초기화 할 때 생성할 초기 커넥션 개수 지정
        ds.setMaxActive(10); // 커넥션 풀애서 가져올 수 있는 최대 커넥션 수
        ds.setMaxIdle(10);
        ds.setTestWhileIdle(true); // 커넥션 Idle(유휴) 상태 검사 여부
        ds.setMinEvictableIdleTimeMillis(1000 * 60 * 3); // Idle상태가 최소 3분으로 지정
        ds.setTimeBetweenEvictionRunsMillis(1000 * 10); // 10초 주기로 Idle상태 커넥션 검사
        return ds;
    }
    
    @Bean
    public PlatformTransactionManager transactionManager() {
        DataSourceTransactionManager tm = new DataSourceTransactionManager();
        tm.setDataSource(dataSource());
        return tm;
    }
 
    @Bean
    public MemberDao memberDao() {
        return new MemberDao(dataSource());
    }
 
 
    @Bean
    public ChangePasswordService changePwdSvc() {
        ChangePasswordService pwdSvc = new ChangePasswordService();
        pwdSvc.setMemberDao(memberDao());
        return pwdSvc;
    }
 
}
Colored by Color Scripter
cs

 

MainForCPS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package main;
 
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
import config.AppCtx;
import spring.ChangePasswordService;
import spring.MemberNotFoundException;
import spring.WrongIdPasswordException;
 
public class MainForCPS {
 
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = 
                new AnnotationConfigApplicationContext(AppCtx.class);
 
        ChangePasswordService cps = 
                ctx.getBean("changePwdSvc", ChangePasswordService.class);
        try {
            cps.changePassword("madvirus@madvirus.net", "1234", "1111");
            System.out.println("암호를 변경했습니다.");
        } catch (MemberNotFoundException e) {
            System.out.println("회원 데이터가 존재하지 않습니다.");
        } catch (WrongIdPasswordException e) {
            System.out.println("암호가 올바르지 않습니다.");
        }
 
        ctx.close();
 
    }
}
 
Colored by Color Scripter
cs

 

Transaction 사용방법: 

 

1. 트렌젝션을 적용하고 싶은 메소드에 @Transactional 어노테이션을 붙인다.

    ex) ChangePasswordServiced의 changePassword() 메소드에 어노테이션을 붙인 모습이다.

 

2. 설정클래스에 @EnableTransactionManagement 어노테이션을 추가한다.

    - 이 어노테이션은 @Transactional 어노테이션이 붙은 메서드를 트랜잭션 범위에서 실행하는 기능을 활성화한다.

 

3. 설정 클래스에서 PlatformTransactionManager 빈을 설정해준다.

    - 구현기술에 상관없이 동일한 방식으로 트랙젝션을 처리하기 위해 이 인터페이스를 사용한다. 

    - JDBC는 DataSourceTransactionManager클래스를 사용한다. 

 

4. main클래스에서 구현해 보자. 

   - 19행에서 try catch finally문을 활용해 changePassword메소드를 실행했다. 

 

 

Transaction은 기본적으로 AOP 성격을 띄고 있다. 

@EnableTransactionManagement는 @EnableAspectAutoProxy와 유사해서 두 어노테이션 모두

공통적으로 속성 proxyTargetClass, order를 가진다. 

proxyTargetClass의 기본값은 false이고 false일 경우 인터페이스를 이용해 프록시를 생성하고 true인 경우는 자바 클래스를 이용해 프록시를 생성한다. 

order는 AOP적용 순서를 지정한다. 숫자가 낮을 수록 우선순위이다. 

 

 

@Transactional의 주요 속성 

 

value - PlatformTransactionManager 빈의 이름 지정/ 기본값: ""

propagation - 전파 타입을 지정/ 기본값: REQUIRED

isolation - 격리 레벨 지정/ 기본값: DEFAULT

timeout - 트렌젝션 제한시간 지정

 

 

출처: 초보 웹 개발자를 위한 스프링5 프로그래밍 입문

    'Spring/Spring기본' 카테고리의 다른 글
    • MVC 1.5: 컨트롤러 구현 없는 경로 매핑(addViewController), ModelAndView, 커맨드 객체의 중첩과 콜렉션 프로퍼티를 뷰 jsp에서 사용하는 방법, Controller에서 모델을 통한 값 전달
    • MVC 1: 요청 매핑 어노테이션, 리다이렉트, 요청 파라미터 접근, 커맨드 객체, 폼태그
    • JdbcTemplate를 이용한 DB연동
    • DriverManager를 활용한 JDBC 연동 기초
    Per ardua ad astra !
    Per ardua ad astra !
    개발자 지망생이며 열심히 공부하고 기억하기 위한 블로그입니다.

    티스토리툴바