Spring

[Spring] 트랜잭션

별토끼. 2017. 8. 3. 13:18
반응형

[Spring] 트랜잭션




  • Custom Exception 처리하기
1.
- home.jsp에 링크 걸기
1
2
    <li><a href="test01.do?name=kimgura">테스트1</a></li>
    <li><a href="test01.do">테스트2</a></li>
cs


2.

- HomeController.java

- test01 request를 받을 경우 전달받는 parameter가 있다면 정상적으로 처리

- default Param을 hello로 하여 hello값을 받을 경우 CustomException으로 처리되도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19


    @RequestMapping("/test01")
    public ModelAndView test01(@RequestParam(defaultValue="hello"String name) 
            throws Exception{
        
        ModelAndView mView=new ModelAndView();
        mView.addObject("msg","정상적으로 처리 되었습니다.");
        mView.setViewName("test/result");
        
        //임의의 test !
        if(name.equals("hello")){
            //예외 객체 생성해서 던지기
            throw new CustomException("파라미터가 전달이 안됬네?");
        }
        
        return mView;
    }
    
cs


3.

- CustomException.java

- CustomException 클래스 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class CustomException extends Exception{
    private String message="사용자 정의 Exception";
    
    //생성자 
    public CustomException(String message){
        this.message=message;
    }
    //setter
    public void setMessage(String message) {
        this.message = message;
    }
    //getter
    public String getMessage() {
        
        return message;
    }
}
 
cs


4.

- CustomException 타입의 예외 발생시 처리할 메소드 (HomeController.java)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    /*
     * CustomException type의 예외가  발생하면 예외를 처리할 메소드
     */
    @ExceptionHandler(CustomException.class)
    public ModelAndView handleException1(CustomException ce){
        // 메소드의 인자로 예외 객체가 전달된다.
        
        // 에러 페이지로 보내고 싶으면 ModelAndView 객체를 생성해서 리턴
        ModelAndView mView=new ModelAndView();
        // msg 라는 키값으로 예외 메세지를 담는다.
        mView.addObject("exception", ce);
        mView.setViewName("error/custom");
        return mView;
    }
cs


5.



  • Transaction 처리하기


- 10개의 실행중 하나라도 Exception 발생하면 처음으로 되돌려야 한다.

- 이를 트랜잭션 작업이라고 한다.

- spring에서 트랜잭션 작업을 관리해준다.


1.

home.jsp

1
2
3
    <li><a href="shop/signup_form.do">쇼핑몰 회원가입</a></li>
    <li><a href="shop/deposit_form.do">입금</a></li>
    <li><a href="shop/buy_form.do"></a></li>
cs



2. 

테이블 생성하기

1
2
3
4
5
6
7
8
9
10
11
12
CREATE TABLE client_account
(id VARCHAR2(20PRIMARY KEY,
balance NUMBER CONSTRAINT CHECK(balance >= 0DEFAULT 10000
bonusPoint NUMBER DEFAULT 0);
 
CREATE TABLE delivery
( num NUMBER PRIMARY KEY,
  name VARCHAR2(20),
  addr VARCHAR2(30)
);
 
CREATE SEQUENCE delivery_seq;
cs


3.

shopDto 생성하기

shopDao, shopDaoImpl 생성하기

1
2
3
4
5
6
7
public interface ShopDao {
    public void signup(String id);             //회원가입
    public void deposit(ShopDto dto);         //입금
    public void withDraw(ShopDto dto);        //출금
    public void addPoint(ShopDto dto);        //포인트 적립
    public void requestDelivery(ShopDto dto); //배송요청
}
cs

shopService, shopServiceImpl 생성하기

1
2
3
4
5
6
public interface ShopService {
    public void signup(String id);        //회원가입 처리
    public void deposit(ShopDto dto);    //입금 처리
    public void buy(ShopDto dto);        //상품 구입 처리 
}
 
cs


4.

signup_form.jsp, buy_form.jsp. 생성하기


5.

- ShopServiceImpl.java 에서 buy 메소드 실행 시, withDraw

※ 이 때, 상품 구입 처리시 Dao에서 balance값이 0 이하로 처리될 경우 DataAccessException이 발생한다.

(@Repository 어노테이션으로 bean 으로 만든 Dao 에서 DB 관련 작업을 하닥 발생하는 Exception은

DataAccessException 이다.)

1
2
3
4
5
6
7
8
9
10
11
    @Override
    public void buy(ShopDto dto) {
        //1. 보너스 포인트를 적립하고
        int point=(int)(dto.getMoney()*0.1); //보너스 포인트를 계산해서
        dto.setPoint(point); //Dto에 넣어주고
        shopDao.addPoint(dto); //DB에 반영
        //2. 계좌 잔액을 줄이고
        shopDao.withDraw(dto);
        //3. 배송 정보를 입력한다.
        shopDao.requestDelivery(dto);
    }
cs


  • DataAccessException 처리하기

6.

- servlet-context에 추가

1
xmlns:tx="http://www.springframework.org/schema/tx"
cs


1
2
3
4
5
6
7
8
    <!-- Spring Transaction Manager 설정 -->
    <bean id="txManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <!-- 어노테이션으로 트렌젝션을 적용할 위치를 지정할수 있도록 -->
    <tx:annotation-driven transaction-manager="txManager"/>
cs


7.

- @Transactional 을 해주면 spring에서 관리해준다.



8.

- @Repository 어노테이션으로 bean 으로 만든 Dao 에서

- DB 관련 작업을 하닥 발생하는 Exception은

- DataAccessException 이다.

- @ExceptionHandler : 종류별로 다른 Exception처리 하도록 도와준다.

1
2
3
4
5
6
7
8
9
 
    @ExceptionHandler(DataAccessException.class)
    public ModelAndView handleDataAccess(DataAccessException dae){
        
        ModelAndView mView=new ModelAndView();
        mView.addObject("exception", dae);
        mView.setViewName("error/data_access");
        return mView;
    }
cs


  • Dao에서 특정상황 CustomException 발생시키기

9.

1
2
3
4
5
6
7
8
9
10
11
12
/*
 * Dao 에서 특정 상황에 발생시킬 Custom Exception 클래스 정의하기
 */
public class NoDeliveryException extends DataAccessException{
    
    //생성자
    public NoDeliveryException(String msg){
        //생성자의 인자로 전달 받은 문자열을 부모 생성자에 전달한다.
        super(msg);
    }
}
 
cs


10.

- Dao에서 예외 발생시키기

1
2
3
4
5
6
7
    @Override
    public void requestDelivery(ShopDto dto) {
        session.insert("shop.requestDelivery", dto);
        
        //특정 상황이 발생했다는 가정하에서 예외 발생 시키기
        throw new NoDeliveryException("눈이와서 배송을 못해요");
    }
cs


11.

- Custom Exception 발생 시 Controller

1
2
3
4
5
6
7
8
    @ExceptionHandler(NoDeliveryException.class)
    public ModelAndView handleNoDeliveryException(NoDeliveryException nde){
        
        ModelAndView mView=new ModelAndView();
        mView.addObject("exception", nde);
        mView.setViewName("error/data_access");
        return mView;
    }
cs


반응형