83일 차 - 트랜잭션과 예외처리 (23.04.26)

yvonne·2023년 4월 26일
0

📂Spring

목록 보기
15/18
post-thumbnail

4. @Transactional 과 Checked / UnChecked Exception 과의 관계

  • 예외에 따른 롤백처리: Checked 예외는 롤백되지 않고, UnChecked 예외는 롤백됩니다.
  • Checked Exception 일때는 Rollback을 하지 않는다.
  • @Transactional(rollbackFor = Exception.class) 옵션으로 모든 예외에 대해서 롤백할 수 있다.

  • 기본적으로 @Transactional 은 unChecked Exception 과 error 객체 대상으로 롤백시킴
  • Checked Exception도 롤백 시키고 싶으면, rollbackFor = Exception.class을 쓰면 됨.

✔ LoginController.java

package edu.global.ex.controller;

import java.security.Principal;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import edu.global.ex.service.UserService;
import edu.global.ex.vo.UserVO;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
public class LoginController {

	@Autowired
	private UserService userService;

	@Autowired
	private PasswordEncoder encoder;

	@GetMapping("/login")
	public String login() {
		log.info("login() ..");
		return "login/login";
	}

	@RequestMapping(value = "/loginInfo", method = RequestMethod.GET)
	public String loginInfo(Authentication authentication, Principal principal, Model model) {

		String user_id;

		// 1.SpringContextHolder를 통하여 가져오는 방법(일반적인 빈에서 사용 할수있음 )
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		user_id = auth.getName();
		System.out.println("유저 아이디:" + user_id);

		// 2.authentication 객체로 가져오는 방법(많은 )
		System.out.println("authentication 유저 아이디:" + authentication.getName());
		System.out.println("authentication 권한들:" + authentication.getAuthorities());

		// 3.Principal 객체로 가져오는 방법(가져올수 있는게 getName() 정도
		System.out.println("Principal 유저 아이디:" + principal.getName());

		return "redirect:/";
	}

	@GetMapping("/addUser/{id}/{pw}") // url을 파라미터로 받는 restful 방식
	public String addUser(@PathVariable String id, @PathVariable String pw) throws Exception {
		System.out.println(id + ":" + pw);
		UserVO user = new UserVO();
		user.setEnabled(1);
		user.setUsername(id);
		user.setPassword(encoder.encode(pw.toString().trim()));

		System.out.println(user);

	//	userService.addUser(user);
	//	userService.addUser2(user);
	//	userService.addUser3(user);
    //	userService.addUser4(user);
	//	userService.addUser5(user);
		userService.addUser6(user);
		
		return "redirect:/";
	}
}

✔ UserSerivce.java

package edu.global.ex.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import edu.global.ex.mapper.UserMapper;
import edu.global.ex.vo.UserVO;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class UserService {

	@Autowired
	private UserMapper userMapper;

	// 1.정상 동작 코드 => User를 insert를 넣은후 권한 까지 insert 해야 됨 => 2개가 정상적인 동작이 되어야 됨(트랜잭션
	// 단위)
	public void addUser(UserVO user) {
		log.info("addUser()..");

		userMapper.insertUser(user); // User를 insert를 넣은후
		userMapper.insertAuthorities(user); // 권한 설정
	}
	
	// 2. 아래를 실행하면 user테이블에는 들어가 있지만 authorities테이블에는 들어가있지 않음 
	
	public void addUser2(UserVO user) {
		log.info("addUser2()..");
		
		userMapper.insertUser(user); // User를 insert를 넣은후
		user = null; // 일부러 null 넣어서 에러 생성
		userMapper.insertAuthorities(user); // 권한 설정
	}
	
	// 3. Transactional을 붙이면 롤백이 되어 아무런 데이터가 들어가지 않음
	@Transactional
	public void addUser3(UserVO user) {
		log.info("addUser3()..");
		
		userMapper.insertUser(user); // User를 insert를 넣은후
		user = null; // 일부러 null 넣어서 에러 생성
		userMapper.insertAuthorities(user); // 권한 설정
	}
	
	// 4.checked Exception을 강제로 시켜 봄  📍 롤백 되지 않음
	@Transactional
	public void addUser4(UserVO user) throws Exception {
		log.info("addUser4()..");

		userMapper.insertUser(user); 
		userMapper.insertAuthorities(user);

		// throw Checked Exception
		throw new Exception("Exception (Checked Exception)");
	}
	
	// 5.UnChecked Exception을 강제로 시켜 봄  📍 롤백 됨
	@Transactional
	public void addUser5(UserVO user) throws Exception {
		log.info("addUser5()..");

		userMapper.insertUser(user); 
		userMapper.insertAuthorities(user);

		// throw Checked Exception
		throw new RuntimeException("RuntimeException (UnChecked Exception)");
	}
  
	// 6. rollbackFor 옵션을 준다 📍 롤백 됨
	@Transactional(rollbackFor = Exception.class) // rollbackFor 함께 넣는 거 추천 👍
	public void addUser6(UserVO user) throws Exception {
		log.info("addUser6()..");

		userMapper.insertUser(user);
		userMapper.insertAuthorities(user);

		// throw Checked Exception
		throw new Exception("RuntimeException (UnChecked Exception)");
	}
}
profile
개발 연습장

0개의 댓글