[Spring] 트랜잭션
[Spring] 트랜잭션
- Custom Exception 처리하기
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(20) PRIMARY KEY, balance NUMBER CONSTRAINT CHECK(balance >= 0) DEFAULT 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 |