Day62 실습프로젝트(DB커넥션)
ProxyPattern
MultiTread의 문제점
- 하나의 SqlSession을 생성하여 하나의 캐시를 공유한다.
- 하나의 클라이언트에서 커밋을 하면 전체 캐시가 데이터베이스에 업데이트된다.
- 다른 클라이언트에서 오류가 발생해도 롤백되지 않는다.
Factory Pattern
SqlSessionFactory생성
- SqlSessionFactory를 만들어서 쓰레드당 하나의 SqlSession를 갖게 만든다.
- 클라이언트가 접속 후 명령을 수행할때 고유의 SqlSession이 있는지 확인 후 할당한다.
- 그외 다른 기능은 기존의 SqlSession에게 위임한다.
별도 SqlSession 할당
- 각자 고유의 캐시를 가지기 때문에 다른 클라이언트의 작업이 현재 클라이언트의 작업에 영향을 미치지 않는다.
코드 수정
SqlSessionFactory 생성
- GoF의 Proxy 패턴을 적용하여 SqlSessionFactoryProxy 클래스 정의
- SqlSessionFactory의 openSession(boolean) 메서드의 기능 변경
- 스레드 별로 같은 SqlSession 객체를 리턴
1
2
3
4
5
6
7
8
9
10
11
12
13
// 나머지는 원래 SqlSessionFactory에 위임을 한다.
@Override
public SqlSession openSession(boolean autoCommit) {
SqlSession sqlSession = sqlSessionThreadLocal.get();
if (sqlSession == null) {
sqlSession = original.openSession(autoCommit);
}
sqlSessionThreadLocal.set(sqlSession);
return sqlSession;
}
DaoFactory 클래스 변경
- Dao 구현체에서 작업할 때 SqlSessionFactory를 통해 SqlSession 객체를 얻어 사용하도록 변경
1
2
3
4
5
6
7
8
9
private SqlSessionFactory sqlSessionFactory;
public DaoFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
//중략
//sqlSession을 Factory에서 받아는 코드를 추가한다.
SqlSession sqlSession = sqlSessionFactory.openSession(false);
Command 구현체 변경
private SqlSessionFactory sqlSessionFactory;
를private SqlSessionFactory sqlSessionFactory;
으로 변경한다.- commit()/rollback()을 수행할 때 SqlSessionFactory를 통해 SqlSession을 얻어 사용하도록 변경
sqlSession.commit();
을sqlSessionFactory.openSession(false).commit();
으로 변경한다.
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
public class BoardDeleteCommand implements Command {
private BoardDao boardDao;
//sqlSession -> sqlSessionFactory
private SqlSessionFactory sqlSessionFactory;
public BoardDeleteCommand(BoardDao boardDao, SqlSessionFactory sqlSessionFactory) {
this.boardDao = boardDao;
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public void execute(String menuName, Prompt prompt) {
//중략
boardDao.delete(boardNo);
sqlSessionFactory.openSession(false).commit();
prompt.printf("'%s'번 게시글을 삭제 했습니다.\n", deletedBoard.getNo());
} catch (Exception e) {
sqlSessionFactory.openSession(false).rollback();
prompt.println("삭제 중 오류 발생!");
}
}
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.