티스토리 뷰
Service
#Service Layer: 핵심 업무(비즈니스 로직)을 수행한다
Service 클래스 작성하기
인터페이스와 그 구현객체를 생성한다.
각 클래스 위에 @Service를 붙인다. #ComponentScan
인터페이스 [RoleService.java]
1
2
3
4
5
6
7
8
9
|
@Service
public interface RoleService {
public static final int LIMIT = 5;
public Guestbook addRole(Role role);
public int deleteRole(int id);
public List<Role> getRoles();
public int getRoleCount();
}
|
cs |
[RoleServiceImpl.java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
RoleDao roleDao;
@Autowired
LogDao logDao;
@Override
@Transactional(readOnly = false)
public Role addRole(Role role) {
...
return role;
}
@Override
public int deleteRole(int id) {
int deleteCount = roleDao.deleteRoleById(id);
...
return deleteCount;
}
@Override
public List<Role> getRoles() {
return roleDao.selectRoleAll();
}
@Override
@Transactional
public int getRoleCount() {
return roleDao.countRole();
}
}
|
cs |
line 4 Autowired #Autowired
Dao객체를 자동으로 주입한다
Transaction
하나의 비즈니스 로직은 하나의 트랜잭션으로 동작한다
연관된 두 개 이상의 쿼리를 실행할 때, 모든 작업이 끝났을 때 COMMIT을 수행하고 중간에 오류가 발생하면 ROLLBACK하는 것이 기본이다.
1. 트랜잭션의 성질
- 원자성(Atomicity): 한 트랜잭션 내에서 실행한 작업들은 하나로 간주한다. 즉, 모두 성공 또는 모두 실패.
- 일관성(Consistency): 트랜잭션이 진행되는 동안 데이터가 변경되더라도, 처음에 트랜잭션을 진행하기 위해 참조한 데이터로 진행된다. 일관성 있는 데이터베이스 상태를 유지한다.
- 독립성(Isolation): 둘 이상의 트랜잭션이 동시에 실행되고 있을 경우에 서로 영향을 미치지 않아야 한다. 하나의 트랜잭션이 완료될 때까지 다른 트랜잭션에 끼어들 수 없다.
- 지속성(Durability): 트랜잭션을 성공적으로 마치면 결과가 항상 저장되어야 한다.
2. 스프링에서 트랜잭션 사용하기
1. Maven에 Spring tx 의존성 추가 #Maven
1 2
3
4
5
|
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
|
cs |
2. @EnableTransactionManagement #DBConfig
3. 해당 클래스, 메소드 위에 @Transactional을 붙인다
- 트랜잭션 기능이 적용된 프록시 객체가 생성된다. 이 프록시 객체는 @Transactional이 포함된 메소드가 호출 될 경우, PlatformTransactionManager를 사용하여 트랜잭션을 시작하고, 정상 여부에 따라 Commit 또는 Rollback 한다.
addRole
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@Override
@Transactional(readOnly = false)
public Role addRole(Role role) {
int id = roleDao.insertRole(role);
role.setId(id);
// if(1==1) throw new RuntimeException("test exception");
Log log = new Log();
log.setIp(ip);
log.setMethod("insert");
log.setRegdate(new Date());
logDao.insert(log);
return role;
}
|
cs |
line 2 @Transactional
- @Transactional은 다수의 insert, update, delete가 존재하는 메소드에서 사용된다.
- insert, update, delete를 방지하기 위한 용도가 아닌, 조회 시(readOnly=true)에는 @Transactional을 사용하지 않는다.
- mysql의 isolation level: Repetable Read. 동일 트랜잭션 내의 데이터의 일관성을 보장함
line 8 트랜잭션 원자성 테스트: 모두 성공하지 않으면 전부 취소된다.
- role insert 작업 후 일부러 예외를 발생시킨다.
- DB를 살펴보면 아무 작업도 일어나지 않았음을 알 수 있다. 대신 다음 작업 시 role 테이블의 id는 1→3 / log 테이블의 id는 1→2 가 된다.
- @Transactional 어노테이션을 제외하고 테스트하면 role insert만 따로 실행됨을 알 수 있다.
https://goddaehee.tistory.com/167
주요 속성
속성 | 설명 |
사용 예 | ||
isolation | Transaction의 Isolation level. 별도로 정의하지 않으면 DB의 Isolation Level을 따름 | @Transactional(isolation = Isolation.DEFAULT) | ||
propagation | Transaction의 전파규칙을 정의 (Defatult : REQUIRED) | @Transactional(propagation = Propagation.REQUIRED) | ||
readOnly | 해당 Transaction을 읽기 전용 모드로 처리 (Default : false) | @Transactional(readOnly = true) | ||
rollbackFor | 정의된 Exception에 대해서는 rollback을 수행 | @Transactional(rollbackFor = Exception.class) | ||
noRollBackFor | 정의된 Exception에 대해서는 rollback을 수행하지 않음 | @Transactional(noRollbackFor = Exception.class) | ||
timeout | 지정한 시간 내에 해당 메소드 수행이 완료되지 않을 경우 rollback 수행. -1일 경우 no time out (Default : -1) | @Transactional(timeout = 10) |
https://taetaetae.github.io/2017/01/08/transactional-setting-and-property/
'JAVA > Spring' 카테고리의 다른 글
jdbcTemplate multiple queries 에러 (0) | 2019.12.26 |
---|---|
ApplicationConfig @ComponentScan 범위 오류 (0) | 2019.12.22 |
[Spring] RowMapper (0) | 2019.10.12 |
[Spring] Connection Pool / Spring JDBC (0) | 2019.10.10 |
[Spring] Controller(Handler) (0) | 2019.10.09 |