springboot는 기본적으로 Autocommit(true)으로 설정되어 있다.
설정은 applicaion.yml/properties에서 바꿔줄 수 있다.
예시
spring:
datasource:
driver-class-name:
url:
username:
password:
hikari:
auto-commit: false
@Transactional 전에는 update, insert 각각 하나씩 session 처리한다.
service.java
public void doUpdateInsert(List<String> chkList, String price) { log.info("============= price multi update, log insert ==============="); menuDaoV2.doUpdatePriceOne(chkList, price); menuDaoV2.doInsertLogOne(chkList, price); }
log
@Transactional 적용
1. Springboot가 자동으로 autocommit 한다.DEBUG com.zaxxer.hikari.HikariConfig -autoCommit................................true
- @Transactional 적용하면 autocommit이 false가 된다.
@Transactional public void doUpdateInsert(List<String> chkList, String price) { log.info("============= price multi update, log insert ==============="); menuDaoV2.doUpdatePriceOne(chkList, price); menuDaoV2.doInsertLogOne(chkList, price); }
DEBUG o.m.jdbc.message.server.OkPacket -System variable change: autocommit = OFF
- 하나의 DB session에서 update, insert가 처리되는 것을 알 수 있다.
- commit이 완료된다.
DEBUG o.m.jdbc.client.impl.StandardClient -execute query: COMMIT
- 다시 autocommit이 설정된다.
DEBUG o.m.jdbc.message.server.OkPacket -System variable change: autocommit = ON
Rollback
@Transactional - Exception (Checked / Unchecked)
RuntimeException인 경우만 Rollback 처리를 한다.
- Checked Exception(Exception)을 발생시켜 보았다.
@Transactional public void doUpdateInsert(List<String> chkList, String price) throws FileNotFoundException { log.info("============= price multi update, log insert ==============="); menuDaoV2.doUpdatePriceOne(chkList, price); // Checked Exception 발생 지점 File file = new File("not_existing_file.txt"); FileInputStream stream = new FileInputStream(file); menuDaoV2.doInsertLogOne(chkList, price); }
Test 결과
DEBUG org.mybatis.spring.SqlSessionUtils -Creating a new SqlSession DEBUG org.mybatis.spring.SqlSessionUtils -Registering transaction synchronization for SqlSession DEBUG o.m.jdbc.client.impl.StandardClient -execute query: Update coffee_menu set price = CAST(? as INTEGER) WHERE no in (?, ?) DEBUG org.mybatis.spring.SqlSessionUtils -Transaction synchronization committing SqlSession DEBUG o.m.jdbc.client.impl.StandardClient -execute query: COMMIT DEBUG o.m.jdbc.message.server.OkPacket -System variable change: autocommit = ON DEBUG o.s.j.support.JdbcTransactionManager -Releasing JDBC Connection [HikariProxyConnection@287476718 wrapping org.mariadb.jdbc.Connection@478530cb] after transaction =============== Test =============not_existing_file.txt (지정된 파일을 찾을 수 없습니다)
update만 처리되고 commit 된다.
@Transactional(rollbackFor = Exception.class)
Exception도 rollback 될 수 있도록 설정해 줄 수 있다.
- RuntimeException
RuntimeException의 ArithmeticException을 발생시켜 보았다.@Transactional public void doUpdateInsert(List<String> chkList, String price) throws FileNotFoundException { log.info("============= price multi update, log insert ==============="); menuDaoV2.doUpdatePriceOne(chkList, price); // Checked Exception 발생 지점 // File file = new File("not_existing_file.txt"); // FileInputStream stream = new FileInputStream(file); // Unchecked Exception 발생 지점 (ArithmeticException - RuntimeException) int numerator = 1; int denominator = 0; int result = numerator / denominator; log.info("====================== RuntimeException =========================="); menuDaoV2.doInsertLogOne(chkList, price); }
Test 결과
DEBUG o.m.jdbc.client.impl.StandardClient -execute query: ROLLBACK