SpringBoot에서 트랜잭션 처리를 구현합시다.
16219 단어 SpringBoot
SpringBoot에서는 어떻게 해야 할까요?
트랜잭션 처리는 @Transactional 어노테이션에서
예를 들면 이런 느낌의 구현시, insert 처리에 대해서 트랜잭션을 걸고 싶다고 합니다.
(만약 전부의 소스 코드 같은 분은 마지막 분에 gitlab의 URL 붙이고 있으므로 그쪽으로부터 부디)
// IndexController.java
@Controller
public class IndexController {
:
@RequestMapping
public String index(Model model) {
// do something,
}
@RequestMapping(value = "/insert")
public String insert(Model model, @RequestParam("name") String name) {
// do something.
}
:
}
아래와 같이 insert 메소드의 전에
@Transactional
어노테이션을 추가하기만 하면 됩니다.아,
import org.springframework.transaction.annotation.Transactional;
도 필요하네요.// IndexController.java
import org.springframework.transaction.annotation.Transactional; // ←これと
@Controller
public class IndexController {
:
@RequestMapping
public String index(Model model) {
// do something,
}
@Transactional // ← これを追加!
@RequestMapping(value = "/insert")
public String insert(Model model, @RequestParam("name") String name) {
// do something.
}
:
}
이것으로 insert 메소드중의 실행중에 예외가 발생하면 자동적으로 롤백을 해 줍니다. 간단하네요.
뭔가 조심하는 것은 있을까.
롤백하지 않는 예외가 있습니다.
다만, 롤백의 주의점으로서, 비검사 예외(RuntimeException 및 그 서브 클래스)가 발생했을 경우는 롤백되지만, 검사 예외(Exception 및 그 서브 클래스로 RuntimeException의 서브 클래스가 아닌 것)가 발생했을 경우는 롤 백되지 않고 커밋된다.
via : Spring에서 트랜잭션 관리
글쎄. 시도해 봅시다. 예외를 제어하기 쉽기 때문에 update 처리에 예외 처리를 넣을 수 있습니다. 데모 페이지의 과일 이름 바꾸기 > 변경 후 텍스트 영역에
非検査例外
, 検査例外
를 입력하면 각 예외를 throw하는 프로세스가 추가되었습니다.// IndexController.java
@Controller
public class IndexController {
:
@Transactional
@RequestMapping(value = "/update")
public String insert(Model model, @RequestParam("chg_before_name") String before_name,
@RequestParam("chg_after_name") String after_name) throws Exception {
fruitMapper.update(before_name, after_name);
List<Fruit> list = fruitMapper.selectAll();
model.addAttribute("fruits", list);
// トランザクション動作確認
if(after_name.equals("非検査例外")) {
// 非検査例外の時にはロールバックが発生します。
System.out.println("非検査例外発生");
throw new RuntimeException();
}
if(after_name.equals("検査例外")) {
// 検査例外の時にはそのままコミットされます。
System.out.println("検査例外発生");
throw new Exception();
}
return "index";
}
// 例外キャッチ
@ControllerAdvice
public class ExceptionHandlerAdvisor {
@ExceptionHandler
public String catchError(RuntimeException e){
System.out.println("非検査例外キャッチ");
return "error";
}
@ExceptionHandler
public String catchError(Exception e){
System.out.println("検査例外キャッチ");
return "error";
}
}
:
}
동작 확인
비검사 예외, 검사 예외 각각의 움직임을 확인해 봅시다.
비검사 예외일 때
mysql> select * from fruits;
+----+-----------+
| id | name |
+----+-----------+
| 1 | みかん |
| 2 | ばなな |
| 3 | りんご |
+----+-----------+
3 rows in set (0.00 sec)
-- アップデート実行するが、非検査例外である RuntimeException がスローされる。
mysql> select * from fruits;
+----+-----------+
| id | name |
+----+-----------+
| 1 | みかん |
| 2 | ばなな |
| 3 | りんご |
+----+-----------+
3 rows in set (0.01 sec)
みかん
가 非検査例外
로 업데이트 될 것이라고 생각하지만 트랜잭션 처리 중 예외 발생으로 인해 롤백되었습니다. 즉, 갱신 처리는 없었던 것으로 되어 있네요.검사 예외일 때
mysql> select * from fruits;
+----+-----------+
| id | name |
+----+-----------+
| 1 | みかん |
| 2 | ばなな |
| 3 | りんご |
+----+-----------+
3 rows in set (0.00 sec)
-- アップデート実行するが、検査例外である Exception がスローされる。
mysql> select * from fruits;
+----+--------------+
| id | name |
+----+--------------+
| 1 | 検査例外 |
| 2 | ばなな |
| 3 | りんご |
+----+--------------+
3 rows in set (0.00 sec)
비검사 예외 때와 같이 "귤"이 "검사 예외"로 갱신되지 않을 것을 기대하고 있었습니다만, 이번 throw 한 예외는
検査例外
때문에 커밋 되어 버렸습니다.이런 움직임이 있다는 것을 알아 두지 않으면 위험하네요.
실제로 움직이고 싶은 분
자신의 SpringBoot 프로젝트 환경을 동료에게 전달합시다. 을 참고로, 이하의 리포지터리를 클론해 주시면 동작한다고 생각합니다.
# STSプロジェクトを入手します
git clone -b demo_transaction https://gitlab.com/msrx9/sample_springboot_crud.git
# MySQL環境を入手します
git clone https://gitlab.com/msrx9/sample_docker_mysql.git
도움을 준 기사
Reference
이 문제에 관하여(SpringBoot에서 트랜잭션 처리를 구현합시다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/msrx9/items/9db977df275ed2e72dfa텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)