수안이의 컴퓨터 연구실

  • Mainpage
  • About Me
  • Tags
  • Metapage
  • Notice
  • Location
  • Keywords
  • Guestbook
  • Admin
  • Write an Article
  • Total | 1620635
  • Today | 15
  • Yesterday | 482

4 Articles, Search for 'EJB'

  1. 2007/05/18 EJB 기반 프로젝트 수행 가이드 ④
  2. 2007/05/18 EJB 기반 프로젝트 수행 가이드 ③
  3. 2007/05/18 EJB 기반 프로젝트 수행 가이드 ②
  4. 2007/05/18 EJB 기반 프로젝트 수행 가이드 ①
Programming/Java2007/05/18 11:26

EJB 기반 프로젝트 수행 가이드 ④

김주현 (ERP 개발자)
2004/04/26

① 세션빈에서의 DB 접근전략 및 엔터티빈 사용시 주의사항
② 세션빈에서의 트랜잭션 관리
③ 비즈니스 프로세스 구현 최적화하기
④ 능률 높여주는 유틸리티를 사용하자

EJB를 사용하는 프로젝트에서 개발속도를 향상시킬 수 있는 유틸리티에 대해 알아보자. 이 유틸리티들은 개발자가 프로젝트를 시작할때 직접 만들어서 사용하는 것이다.

EJB 스펙을 지원하는 개발툴 중 비주얼 카페, 비주얼 에이지 등을 사용해본 개발자라면 이 툴들이 EJB 개발에 많은 도움을 주지만 소위 ‘무겁다’는 단점이 있음을 느꼈을 것이다.

PC 사양이 받쳐줘야 돌릴 수 있다는 것 외에, 이러한 툴들은 전체 개발을 놓고 볼 때 오히려 개발자의 집중에 저해요소로 작용하는 경우도 빈번하다.

따라서 개발자가 선택하게 되는 최종적인 툴은 바로 텍스트 에디터 프로그램이다. 실제로 개발자들을 보면 비주얼 카페나 비주얼 에이지를 기동시키고 코딩하는 것보다 "텍스트 에디터로 모든 것을 해결하기"를 선호하는 경우가 많다.

텍스트 에디터를 사용하면서 문제는 테이블 하나당 INSERT, DELETE, UPDATE, SELECT라는 DML 문을 DB 래퍼 클래스에 코딩할 때 남은 반복적인 작업을 어떻게 해결하느냐가 될 것이다. 이때 개발자 유틸리티가 필요하다.

DB 래퍼 클래스 자동 생성하기
DB 래퍼 클래스는 주로 테이블 하나당 하나씩 만들게 된다. EMP 테이블에 대한 INSERT, DELETE, UPDATE, SELECT 문을 실행시킬 EmpDb라는 클래스를 만든다고 생각해보자. 필요한 SQL문을 실행시키는 메소드가 나열될 것이다.

개발자는 다음 DEPT 테이블에 대해서도 똑같은 작업을 해야한다. 테이블 컬럼 명이 다르기 때문에 Copy & Paste 작업도 여의치 않다.

이쯤되면 해당 테이블의 컬럼명 정보 및 타입, PK 정보 등을 읽어서 자동으로 메소드들을 생성시켜 주는 유틸리티를 만들어야겠다는 생각이 들 것이다. PC에서 간단히 실행만 시키면 DB래퍼 자바 파일을 만들어주는 유틸리티가 있다면 작업 속도를 향상시키고 능률을 높일 수 있을 것이다.

이 클래스를 실행시키면 먼저 프로퍼티 파일을 읽어와야 한다. 클래스 안에 직접 테이블 명 혹은 DB URL 등을 타이핑해서 쓰는 것 보다, 프로퍼티 파일 안의 테이블 명, 접속 DB 정보 등을 읽어오도록 함으로써 보다 쉽게 활용할 수 있는 방향으로 만들어야 한다.

다음은 해당 DML 문이 적혀있는 파일을 생성시켜야 한다. 이 작업에는 파일을 생성시켜야 하므로 PrintWriter 클래스도 등장하고 프로퍼티 파일을 읽어올 때 Properties 클래스도 써야 할 것이다.

핵심적인 기능인 SELECT 및 DML문 생성 시에는 어떤 클래스가 사용될까.
DatabaseMetaData 인터페이스의 getColumns 메소드와 getPrimaryKeys 메소드를 이용하도록 하자.

아래는 컬럼 어레이를 리턴하는 메소드이다.

소스보기 1




이 메소드를 호출할 시에 catalog, schemaPattern, tableNamePattern, columnNamePattern을 넘기면(주로 catalog나 shema는 null로 넘겨진다) DatabaseMetaData는 받은 조건으로 검색한 후, 해당하는 컬럼이 있으면 그것의 모든 정보를 ResultSet 형태로 가지고 온다. 이를 컬럼 어레이로 받아오는 것이다.

DatabaseMetaData 인터페이스는 DB의 래퍼 클래스와 같은 역할을 하는 것이다. 이제 이 컬럼 정보로 만드는 INSERT문을 보자.

소스보기 2




실행하면 EmpDb.java 파일의 INSERT 문이 아래와 같이 생성될 것이다.

소스보기 3




INSERT 문을 예로 들었는데, 마찬가지 방법으로 SELECT, DELETE, UPDATE 문도 만들 수 있을 것이다.

다만 SELECT 문의 경우 테이블의 Primary Key를 인자로 받을 때와 받지 않을 때, 만들어지게 되는 쿼리가 다르므로 인자로 받는 Primary Key 갯수마다 각각 SELECT 문을 만들어 볼 수도 있다.

이때는 역시 DatabaseMetaData의 getPrimaryKeys 메소드를 이용해 해당 컬럼의 Primary Key 컬럼을 컬럼 어레이로 받아서 작업한다.

SQL문에 더블 쿼테이션을 붙이는 작업
실제 INSERT, DELETE , UPDATE 문은 위 유틸리티의 활용도가 상당히 높다. 하지만 SELECT 문은 역시 개발자의 손이 필요하다. 조회조건이 다양하고, 사용하게 될 표의 형식이 복잡하기 때문에 하나의 테이블에 대해 Primary Key로만 검색하는 SELECT문은 실제로 잘 쓰여지지 않으며 개발자가 쿼리를 새로 만드는 일이 빈번한 것이다.

개발자들은 주로 자신이 만든 쿼리를 SQL 네비게이터나 골든 뷰 등의 툴을 이용해 실행시켜 정상적으로 동작하고 데이터들이 올바로 표시되는 쿼리라는 것을 확인 한 후에 자바클래스의 메소드에 붙이게 된다.

쿼리를 문자열로 바꾸기 위해 더블 쿼테이션 마크를 붙여야 하는데 이 작업을 일일이 하고 있는 것도 체력 및 시간 낭비이므로 아래와 같은 간단한 유틸리티를 사용해 보자.

quotationSample.html

더블 쿼테이션 마크를 붙이거나 제거하는 이 유틸리티는 StringBuffer가 아닌 String을 바로 사용한다. 이를 보고 String은 Immutable이므로 String에 대해 가변적인 작업을 할 때는 StringBuffer를 쓰되, 최종적으로 StringBuffer.toString() 메소드를 쓰는 것이 자원활용 면에서 더 나은 것이 아닌가 하는 생각이 들 수도 있다.

즉 아래의 형태가 아니라,

예제(1)




아래와 같은 형태로 쓴다는 것인데

예제(2)




결론부터 말하자면 예제(1)의 형태를 추천한다. 코드 가독성 면에서 예제(1)이 훨씬 뛰어나고, StringBuffer와 String간의 퍼포먼스는 크리티컬한 정도로 차이가 나지 않는다. 쿼리 실행시 가장 신경 써야할 부분은 쿼리가 최적화된 경로로 실행돼야 한다는 점이다. 따라서 굳이 StringBuffer를 써서 개발 시 손이 더 많이 가고, 나중에 유지보수 할 때 쿼리 읽기가 힘들어지는 단점을 감수하지 않도록 하자.

마치며
2004년 5월이라는 이 시점에 EJB도 그다지 신기술은 아니다. 하지만 EJB 기술을 쓰는 개발자가 많음에도 실제 프로그램 개발 시의 최적화에 대한 가이드로써 공유된 부분은 많지 않다.

“하루에 1000라인 이상 개발할 수 있다”는 능력도 중요하지만, 짧다면 짧은 4회분의 이번 강의를 통해 필자가 전달하려 노력한 것은 실제 프로젝트를 진행하면서 “노동력을 낭비하지 않게 하는 방법들”이다. 작으나마 도움이 됐으면 하는 바램이다. @


http://www.zdnet.co.kr/techupdate/lectu ··· 2C00.htm
"Java" 카테고리의 다른 글
  • 리팩토링을 이용한 자바 성능 최적화 기법 (0)2007/05/18
  • 유연한 참조로 메모리 누수 막기 (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ④ (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ③ (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ② (0)2007/05/18
2007/05/18 11:26 2007/05/18 11:26
Posted by webdizen
Tags DB 래퍼 클래스, EJB, Java, 더블 쿼테이션
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/2995

Leave your greetings.

[로그인][오픈아이디란?]

Programming/Java2007/05/18 11:24

EJB 기반 프로젝트 수행 가이드 ③

비즈니스 프로세스 구현 최적화하기

김주현 (ERP 개발자)  
2004/04/09        

① 세션빈에서의 DB 접근전략 및 엔터티빈 사용시 주의사항
② 세션빈에서의 트랜잭션 관리
③ 비즈니스 프로세스 구현 최적화하기
④ 능률 높여주는 유틸리티를 사용하자

이번 강좌에서는 지난번에 언급한대로 Procedure에 대해 이야기해보겠다.

개발자가 SQL문에 대한 지식이 어느정도 있고 그 외 프로그래밍 언어에 대한 경력이 있다고 해서 언제나 강력한 프로그램을 개발하는 것은 아니며, 그 프로그램이 유지보수 및 재활용성이 뛰어난 프로그램이 될지 장담하지도 못한다. 또 EJB 스펙에 대한 지식이 EJB사용 프로젝트의 성패를 좌우하는 것도 아니다.

개발자의 역량과 함께 정확한 업무분석 및 요구사항 분석에 근거해 효율적으로 계산된 설계가 중요한 변수인 것은 굳이 강조하지 않아도 모두 알 것이다.

‘Stored Procedure’의 사용을 개발자 역량이라는 관점에서 이야기해 보자.

타 시스템에서 사용하기도 하는 공통된 기능, 비즈니스 프로세스의 변화 가능성이 작은 기능, 다수개의 테이블에 정보를 등록 및 변경하게 되는 배치 작업 등은 세션빈 메소드 안에서 쿼리 실행을 통해 구현하는 것을 지양하고 Procedure로 처리할 것을 권한다.

Procedure 사용시 얻을 수 있는 장점 중 첫째로 꼽을 수 있는 것은 성능 향상이다. 보통 조회성 프로그램은 1개의 SELECT문을 실행시키는 것으로 제 역할을 다 하겠지만 실제 업무 시스템에는 조회성 프로그램만 존재하는 것이 아니다.

구매처리 및 회계전표발행, 보험금 수납 등 실제 비즈니스 프로세스에서 내부 쿼리를 이용해 조회해와서 VALIDATION 체크를 하기도 하고, INSERT 또는 UPDATE를 여러 개의 테이블에 할 수도 있다.

단일 비즈니스 프로세스, 즉 하나의 트랜잭션에서 처리해야 하는 세분화된 작업이 다수개일 경우, EXECUTE 되는 쿼리도 여러개 일 수 밖에 없다. 이 메소드를 콜하는 REQUEST가 여러 개이면 그만큼 쿼리 실행도 늘어난다.

이에 비해 한번의 실행으로 세분화된 작업을 진행시키는 Procedure를 이용하면 상당한 성능향상 효과를 보게 될 것이다.

Procedure 사용의 두번째 장점은 유지보수가 손쉽다는 것이다.

비즈니스 프로세스 상의 변화나 오류 등으로 인해 Procedure를 고쳐야 할 일이 발생할 때, 해당 Procedure를 고치고 REPLACE 명령으로 DB에 다시 저장시키는 것 만으로 수정이 완료된다.

Procedure가 사용하는 인자의 갯수가 변경되지 않은 경우라면 이를 호출하는 자바클래스 내부 내용은 손 볼 것이 없다. 만약 Procedure로 처리하지 않고 세션빈 메소드 안에서 처리했다면 어떤 일이 뒤따를까.

자바 소스를 변경시키고, 다시 컴파일해 클래스파일을 서버에 업로드 해야한다. 세션빈 메소드 내에서 변경이 있었다면 세션빈클래스를 컴파일한 다음 JAR 파일을 다시 묶어준 후 업로드한다.

하지만 WAS서버의 클래스로더에 이미 적재되어있는 변경 전 클래스를 변경 후의 클래스로 참조하게 하려면 WAS 서버를 재기동시키는 수 밖에 없다. 그런데 시스템 WAS서버를 개발자 마음대로 재기동시킬 수 있을까? 현재 접속한 사용자들이 있으므로 여의치 않은 일이다. 재기동 가능 시점까지 기다릴 수 밖에 없다.

이렇게 자바소스를 변경하는 것과 비교해 보면 Procedure 유지보수가 얼마나 간편한지 알 수 있을 것이다.

세번째 장점은 보안성과 관련된 것이다. 다른 개발자나 유지보수 인력은 해당 비즈니스 프로세스가 Procedure를 콜하는 형태의 세션빈 메소드만 봐서는 메소드내에서 어떤 비즈니스 프로세스가 처리되는지 알 수 없다. DB에 접속해 Procedure 내용을 확인하고 나서야 알 수 있는 것이다. 비즈니스 프로세스가 DB쪽 TIER에 숨겨져 있는 모듈이 보안성이 더 높다고 말할 수 있다.

이제 직접 Procedure를 만들어 사용하도록 하자. 만약 Procedure에 전혀 개발 경험이 없는 사용자라면 이미 자바코딩으로 구현되어있는 모듈을 Procedure로 바꾸어 보는 작업을 해보는 것도 좋을 것이다.

Procedure도 명명규칙이 있다. 각종 펑션이나 Procedure 등 프로젝트의 담당 DBA가 정하는 명명규칙이 있으니, 그것을 참고해서 이름을 정한다.

필자의 경우에는 자바구문으로 데이터를 핸들링 해놓은 메소드를 Procedure로 모두 고치는 작업을 하기도 하고(이러한 경우는 FULL TEST를 반드시 거친후 자바클래스 실행시 결과물과 Procedure의 결과물이 같은지 확인한다), 개발하는 시점부터 Procedure를 도입하여 개발하기도 한다.

아래와 같은 간단한 샘플 Procedure를 보도록 하자.




위 Procedure는 자신이 받은 4가지 인자를 갖고 TEST_TABLE_01 테이블의 ROW를 검색 후, UPDATE를 치고 TEST_TABLE_02에 INSERT나 UPDATE를 한다.

보다시피 if then/else 구문을 활용할 수 있다는 것 뿐 아니라, 위의 예시에는 없지만 for 루프 구문도 사용할 수 있는 등 쿼리와 절차적 프로그래밍을 동시에 할 수 있다는 강점이 있다.

다음은 몇가지 유의할 점.

자바 코딩을 하다가 Procedure 코딩을 하게 되면 가끔 주석을 "//"로 표기하는 실수도 하게 되는데(아니라고 알고는 있지만 습관 때문에 손은 그렇게 타이핑을 하고 있다) Procedure 작성시 "//"라는 주석처리는 존재하지 않으며, "/* * /"로 처리해야 한다.

또한, 변수 명 앞에 "v_" 를 붙이는 명명규칙을 가지고 가는 것이 좋다. 자칫 오라클 예약어를 실수로 변수명으로 사용할 경우, 컴파일 및 실행시에 에러가 떨어지지는 않지만 실행결과가 개발자의 의도대로 산출되지 않게 되므로 변수명 앞에 이와 같은 문자를 달아주는 습관을 갖는게 좋다.

이제 위의 샘플 Procedure를 호출하게 되는 흐름이 어디서부터 시작되는지 세션빈 메소드부터 살펴보기로 하자.



2회 강좌를 본 사람을 알겠지만, 세션빈 메소드는 UsePcDB라는 이름의 DB래퍼 클래스의 메소드를 호출하는 것으로 임무를 마치고 있다. 그렇다면 UsePcDB 클래스의 usePcMethod 메소드는 어떤 내용일까? 아래 소스를 보자.




CallableStatement는 PreparedStatement를 상속받은 인터페이스로써, Procedure를 실행시킬때 사용된다. usePcMethod 메소드의 역할은 PC_TEST라는 이름의 Procedure를 콜하고 실행시키는 것으로 끝난다.

세션빈은 UsePcDB라는 클래스에게 일을 시키고, UsePcDB라는 클래스는 PC_TEST라는 Procedure에게 일을 시킨 셈이다. 실질적인 처리는 모두 PC_TEST Procedure가 하게 되는 것이다.

Procedure를 세션빈에서 사용하게 되는 패턴은 이것으로 대략 소개를 마친다. 한가지 덧붙일 말은 Procedure를 위와 같이 절차적 프로그래밍을 대신하기 위해서만 사용하는 것은 매우 제한적인 활용이라는 점이다. 성능, 보안, 유지보수의 간편함이라는 장점이 있지만, 자바코딩을 대신하는 듯한 절차적 활용에만 머물지 말고 대량의 데이터를 한번에 처리하는 작업에도 활용하는 것이 좋다.

DBMS는 데이터 I/O 시 블럭단위로 처리하고 있으므로, ROW 하나당 작업을 처리하는 Procedure를 1만번 콜하는 식으로 작업을 하는 것은 블럭단위 처리라는 효율적 도구가 있음에도 내버려두고 있는 셈인 것이다. 1만개의 ROW든 100만개의 ROW든 일괄 처리하게 하는 Procedure를 만들어서 활용하는 게 가장 최적화된 처리일 것이다.

감가상각계산등과 같은 비즈니스 프로세스를 예로 들어보자. 각 기업마다 취득중인 모든 자산 물품에 대해 연결산시 감가상각계산을 하게 되는데, 대부분 프로그램에서는 개별 자산번호마다 계산을 끝낸 후 감가상각계산 테이블에 INSERT 하도록 처리를 해놓고 있다.

그러나 감가상각계산이라는 비즈니스 프로세스가 자산번호마다 계산방법이 다른 것이 아니고 정률법 정액법 등 어떠한 계산방법을 취할 것인지, 해당자산이 그 해에 폐기됐는지와 같은 계산할 조건이 다른 것일 뿐, 모든 자산에 대해서 감가상각 계산방법은 동일하다.

각 기업마다 보유하고 있는 물품의 수가 적게는 1000개에서 많게는 만 단위가 넘어가는데, 1건 계산할때 0.5초가 걸린다 해도 자산이 1만건이면 5000초가 소요되는 것이다. 이런 경우에서는 계산의 주체가 세션빈인지, Procedure인지가 문제되는 것이 아니라, for loop 문을 이용하여 건별로 계산시킨다는 것이 문제다. Procedure를 하나 만들어서 감가상각계산할 범위만 인자로 던져준 후, 일괄 처리하도록 해야 한다.

이처럼 DB의 블럭단위 I/O를 일괄처리기법에 활용하는 것이 값비싼 DBMS를 쓰는 진정한 이유라 할 수 있다.

다음 강좌에서는 엔터티빈 없이 진행되는 EJB 프로젝트에서 유용하게 쓰이는 유틸을 소개하도록 하겠다. @


http://www.zdnet.co.kr/techupdate/lectu ··· 2C00.htm
"Java" 카테고리의 다른 글
  • 유연한 참조로 메모리 누수 막기 (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ④ (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ③ (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ② (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ① (0)2007/05/18
2007/05/18 11:24 2007/05/18 11:24
Posted by webdizen
Tags EJB, Java, Procedure
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/2994

Leave your greetings.

[로그인][오픈아이디란?]

Programming/Java2007/05/18 11:22

EJB 기반 프로젝트 수행 가이드 ②

세션빈에서의 트랜잭션 관리

김주현 (ERP 개발자)  
2004/03/30        

① 세션빈에서의 DB 접근전략 및 엔터티빈 사용시 주의사항
② 세션빈에서의 트랜잭션 관리
③ 비즈니스 프로세스 구현 최적화하기
④ 능률 높여주는 유틸리티를 사용하자

지난 강좌에서는 세션빈 내에서 DB를 핸들링하는 데에는 JDBC 드라이버를 이용한 Connection 객체를 사용하는 방법과, 엔터티빈을 이용하는 방법이 있다고 언급했다. 중요한 점은 두가지 방법을 혼용하는 것이 아니라 엔터티빈 사용시 발생하게 되는 문제점을 미리 알고 엔터티빈 사용을 지양하자는 것이다.

지난번 강좌에 이어 엔터티빈 사용을 지양할 수 밖에 없는 사례 한 가지를 더 예로 들겠다.

통상 SI 프로젝트에서 인사시스템과 같이 개인의 정보보안이 엄격히 다루어져야 하는 성격의 시스템인 경우, 업무 전반 모두를 웹기반으로 구현하지는 않는다. 물론 웹으로 구현하는 것과 보안과는 별개의 문제이지만, 아직도 공기업 등에서는 웹기반 구현을 꺼리는 경우가 많기 때문이다.

급여계산 및 업무평가점수계산 등 민감한 성격의 정보를 다루는 프로그램은
클라이언트/서버(C/S) 환경으로 구축돼 업무 담당자만 사용 할 수 있도록 하고, 웹으로는 일반사원들이 자신의 정보를 확인하는 조회성 프로그램만으로 구성되도록 요청하는 사례가 많다.

조회성 기능만 갖고 있는 웹기반 프로그램을 설계한다면, 설계자는 DB의 레코드를 SELECT하고 화면에 보여주는 기능만을 수행하므로 쿼리보다는 엔터티빈을 활용하겠다는 기준을 세우고, 실제 개발도 엔터티빈을 이용해 진행하게 된다.

C/S 환경 시스템과 웹프로그램은 서로 업무 범위 및 구축된 환경만 다를 뿐이지 물리적으로 같은 DB를 사용하고 있다. 이러한 환경에서 간혹 발생하는(주로 동시사용자수가 증가할 때 발생한다) EJB 컨테이너의 ‘NoSuchObjectException’ 장애물을 알아둬야 한다.

C/S 프로그램으로 업무를 하는 담당자와 일반 사용자가 같은 레코드를 조회한 상태에서, 담당자가 해당 레코드를 수정 혹은 삭제했고, 웹의 클라이언트 모듈이 해당 레코드를 표현하는 엔터티빈을 계속 참조하고 있는 상황이라면 NoSuchObjectException을 보게 될 것이다.

이 Exception을 던지는 일은 EJB 컨테이너의 기능 중 하나로 엔터티빈의 객체정보와 실제 DB의 정보가 일치하지 않을 경우 동작하게 된다. EJB 컨테이너는 실제 DB와 엔터티빈 객체를 동기화하고 있기 때문에 다른 세션이 자신이 참조하고 있는 DB의 레코드를 변경했을 경우 Exception을 던지는 것이다.

이 Exception이 발생하면 이를 해결하는 방법은 컨테이너가 참조하고 있는 엔터티빈을 핫디플로이 시켜서 객체를 다시 참조케 하거나, 핫디플로이 방법을 쓸 수 없다면 EJB 서버를 RESTART하는 수 밖에 없다.

컨테이너가 NosuchObjectException을 던질 경우 자동으로 엔터티빈을 Passivate시키고 Activate시키면 편리하겠지만 아쉽게도 그런 기능은 없다. 개발자가 향후에 NosuchObjectException이 생기지 않도록 프로그램마다 빈의 라이프싸이클을 제어하는 부분을 추가하는 방안도 생각해 볼 수 있겠지만 그 작업은 시간 소모가 크다.

해당 엔터티빈의 실행 중 정보를 갖고 있는 XML 데이터의 값 중에서 이러한 에러를 일으키지 않도록 해주는 속성이 무엇인지 안다면, XML 데이터의 값을 고치고 다시 디플로이 하는 방법도 있겠다.

하지만 개발자 입장에서는 본인의 판단 착오와는 전혀 관련이 없는 에러를 맞닥뜨리게 된 것이며, 이미 에러를 발견한 이후에 작업을 하는 것이므로 이미 사용자의 프로그램에 대한 신뢰도가 떨어져있는 상황이겠다. 또한 시스템 내의 모든 엔터티빈을 찾아내 작업을 하기도 꽤 번거로운 일일 것이다.

컨테이너의 동기화 기능이 유발시키는 NoSuchObjectException과 엔터티빈과 매핑되는 테이블이 컬럼이 추가되는 등의 변경 사항이 있을 시 엔터티빈의 소스를 고쳐 다시 디플로이 해야 한다는 문제점으로 인해, 항상 시간에 쫓기는 프로젝트 개발자 입장에서는 엔터티빈의 스펙때문에 자신의 보폭이 좁아지는 느낌을 받을 것이다
.
그리하여, 기존 시스템은 엔터티빈을 이용하되 추가 프로젝트에서는 엔터티빈을 전혀 사용하지 않고, DB핸들링은 100% SQL문으로 처리하고 있는 싸이트도 생기게 된다.

엔터티빈을 쓰지 않으면 DB의 테이블마다 SELECT, DELETE, INSERT, UPDATE 등의 쿼리를 일일이 개발자가 생산해야 하지 않느냐는 의견도 나올 수 있으나 프로젝트 프로토타이핑 단계시점 등에 테이블당 쿼리문을 자동으로 생성시켜주는 간단한 유틸 프로그램을 직접 만들어 사용한다면 생산성이 비약적으로 높아질 수 있다.(4회 강의에서 이 유틸을 소개할 예정이다.)

엔터티빈 사용시 발생하게 되는 문제점에 대한 이야기는 여기서 마무리하고, 초점을 세션빈으로 돌리자. 세션빈 내에서 비즈니스 처리를 할 때 유의해야 할 점이 무엇인지 알아본다.

비즈니스 프로세스와 트랜잭션
하나의 비즈니스 프로세스가 처리될 때 가장 중요하게 지켜져야 할 사항은
트랜잭션이 결함없이 처리되어야 한다는 점이다. 예를 들어 보험금 수납시에 보험담당자의 실적이 체크됨과 동시에, 회계장부에 보험금이 기록되어야 하는 [보험금수납]이란 이름의 업무정의가 있을 경우, 이 업무가 성공적으로 완료되었다고 판단할 수 있는 것은 단 2가지 외에는 없다.

실적도 체크되지 않고 장부에도 기록되지 않은 경우와, 실적 체크와 장부 기록 둘 다 성공한 경우다. 이 외 둘 중 하나만 성공한 경우는 트랜잭션이 실패한 것이다. 시스템 운영상 결코 발생해서는 안되는 치명적인 결함이다.

세션빈이 수행하는 메소드안에서 반드시 트랜잭션이 성공해야 함은 아무리 강조해도 지나치치 않을 것이다.


EJB 컨테이너와 트랜잭션
EJB 개발자들은 세션빈의 메소드 단위로 트랜잭션 레벨을 설정할 수 있다는 것을 알고 있다. 또한 컨테이너가 개발자가 설정한 트랜잭션의 레벨에 따라 메소드 내의 트랜잭션을 하나로 묶어준다는 것도 알고 있다.

EJB의 실행중 속성정보를 갖고 있는 XML 파일안을 조작함으로써 트랜잭션 관리가 필요한 메소드를 지정할 수 있고(기본값은 ALL이다), 레벨 또한 조작할 수 있다.
설정 레벨은 REQUIRED로 지정한다(트랜잭션을 관리할 필요가 없는 업무정의가 존재하는 경우는 없다고 봐도 좋다).

컨테이너는 이 두 가지 정보를 가지고 메소드 시작시점부터 완료시점까지 Exception이 발생하게 되면 레벨이 REQUIRED일 경우 Exception발생 전까지 수행했던 작업을 모두 롤백시킨다.

설정레벨을 하위로 조정하면 Exception을 던지되 롤백시키지는 않는 현상이 벌어진다. 그러므로 이 XML의 기본값을 고치는 경우는 없고, 고쳐서도 안된다. VisualCafe와 같이 자동으로 EJB의 XML을 생성시켜주는 툴에서부터 모두 이 옵션을 기본적으로 REQUIRED로 설정하고 있다.

이렇게 트랜잭션을 컨테이너가 메소드 단위로 관리하므로 개발자 입장에서는 명시적으로 트랜잭션을 ON/OFF 하는 기능을 구현할 필요 없이 일정부분 태스크가 줄어든 상태로 볼 수 있다.

하지만 메소드 내에서 Connection을 씀에 있어 언제 Connection을 얻어오고 반환해야 할 지, 또는 Connection 객체를 몇 개 선언해 생성시켜 쓸 것인지와 같은 고민들은 컨테이너의 기능과 별개로 전체 프로젝트에 일관성 있게 적용되어야 할 표준으로 정해져야 하며, 이는 설계자와 개발자의 몫이다.

Connection 객체 핸들링을 하는 기준
Conection 객체를 어느 클래스가 생성하며 반환할 것인가, DB 래퍼 클래스의 메소드와 통신할시 Connection 객체를 넘길 것인가 말 것인가, 넘긴다면 어떤 방법으로 넘기는가에 대한 기준을 세워야 한다.

세션빈 Connection을 선언하고 생성시켜 얻어오는 주체는 1회 강의에도 말했듯이 세션빈 클래스이다. 세션빈 클래스 안에서 Connection 객체는 전역변수로 선언하지 말아야 한다.

각각의 메소드마다 지역변수로 선언하여 사용하는 것이 효과적이다. 또한 메소드안의 프로세스가 진행 완료됐을 경우, finally 절에서 반드시 Connection을 반환해야 하는 것도 중요한 원칙 중 하나다. 커넥션을 얻어올 때, SQLException을 던져야 하므로 try, catch문을 사용하게 되는데, finally 절에서 반드시 커넥션을 반환하도록 하자.

생성된 Connection 객체는 DB와의 작업을 모두 한 이후 반드시 close 메소드를 통해 닫혀져야 하는데, Connection 객체가 반환되지 않는 경우 심각한 시스템 자원낭비를 유발하게 된다. 이는 곧 프로그램의 운용성능 저하로 이어진다.

Connection 객체생성은 언제나 close() 메소드와 쌍을 이루어야 한다는 식의 사고습관을 가져야 하겠다.

다음으로 언급할 것이 DB 래퍼 클래스와의 통신 패턴이다. DB 래퍼 클래스는 DB에 SELECT, INSERT, DELETE, UPDATE 쿼리를 전달하는 역할을 하는 메소드 집합체로써, DB와 가장 가까운 층이다.

세션빈 메소드는 복잡한 비즈니스 프로세스를 구현하게 되는데, 메소드 시작 부터 끝까지 Connection 객체를 통한 쿼리실행이 모두 그 안에 나열돼 있다면 유지보수 하는 사람 뿐 아니라 개발하는 당사자조차도 가독하기 힘들다.

따라서 DB 래퍼 클래스를 만들어서 쿼리실행에 필요한 인자(사용자가 입력한 조회조건 또는 사용자가 입력한 정보)를 세션빈이 전달하고, 실행 결과를 서로 주고 받는 패턴을 사용한다.

이처럼 DB래퍼 클래스를 통해 레코드를 조작하게 될 때, 세션빈이 생성한 Connection 객체를 DB 래퍼 클래스의 메소드에 콜할 때 인자로 함께 넘겨야한다.

세션빈이 Connection을 넘기지 않고 DB래퍼 클래스에게 Conenction을 핸들링하는 것을 맡길 경우, 5개의 DB래퍼 클래스 메소드를 호출하면 Connection 생성을 5번 하고, close() 명령을 통한 반환도 5번 일어나게 되는 셈이다. 다분히 비효율적이다.

이에 비해 DB래퍼가 자신을 호출한 클래스로부터 항상 Connection을 받아서 쓴다면 필요없는 자원낭비를 막을 수 있다.

이와 같은 원칙은 전체 시스템 구조에서 통일성 있게 적용돼야 할 것이다. 통일성 있게 적용되지 않으면 이런 원칙을 세우는 의미가 없다. 어떤 서브 패키지는 DB래퍼 클래스를 생성할 때 생성자에서 Connection을 받는다던가,
또는 아예 DB래퍼 클래스로 하여금 Connection을 관장하도록 한다던가 하면 전체 설계구조에 통일성이 없고 이를 바탕으로 한 추가 개발에 있어서도 비효율이 따르게 된다. 일관성 없는 구조의 클래스들을 재활용하는 신규 모듈도 역시 흐름에 일관성이 없을 것이다.

이제까지 언급했던 원칙을 패턴으로 사용하는 샘플소스를 보도록 하자.

아래 메소드는 사용자가 입력한 전표 내용으로 전표 등록을 하는 메소드이다. 이 세션빈 이름은 SlipManager이다.



전표를 등록하는 비즈니스 프로세스는 사용자가 입력한 전표정보를 받아서 마감여부를 체크한 후, 전표 번호 MAX 값을 알아내고 전표 TABLE에 INSERT 하는 작업으로 요약된다. 물론 실제 업무는 이보다 훨씬 더 복잡한 경우의 수를 가지고 있다. 법인카드사용정보가 있는 경우 법인카드 사용정보에도 등록을 시켜야 하고, 예산에서 지출되는 전표일 경우 예산 정보에도 그 내역을 기록해야 하는 등 다양한 업무 정의를 포함하고 있다.

소스를 보면 알겠지만 위에서 정한 원칙대로 Connectin 객체는 지역변수로 선언하여 사용하고 있으며, DB래퍼 클래스의 메소드에 Connection 객체를 넘기고 있다.

메소드 오버로딩(OVERLOADING)
이제 다른 시스템의 업무가 이 메소드를 사용해야 하는 업무 요구사항이 생길 경우에 대해 살펴보겠다. 인사시스템에 복리후생비 신청정보가 결재자의 승인을 받으면 자동으로 전표가 발행되어야 하는 요구사항이 나왔다 치자.

프로그램 설계자는 전표등록이라는 비즈니스 프로세스를 구현한 메소드가 SlipManager라는 세션빈에 이미 있다는 것을 알고 있으므로, 이 부분은 따로 전표 등록 메소드를 만들지 않고 기존 것을 재사용하기로 한다.

아래소스는 이처럼 위의 세션빈을 전표등록 메소드를 호출하는 복리후생비 신청정보 승인 프로세스를 보여주고 있다.

소스보기
 



위 소스를 보면 전표등록 메소드를 재사용 하고 있으나 한가지 우려되는 점이 있다. 바로 세션빈의 메소드를 콜 하는 것 까지는 문제가 없으나, 전표 등록 호출시 세션빈에게는 Connection 객체를 던지지 않으므로 호출되는 세션빈이 Connection을 따로 생성시켜 작업을 하고 있다.

위와 같은 업무에서는 세션빈의 메소드를 한번 호출하고 있지만 만약 사용자가 업무 복리후생비전표를 100장 생성시켜야 하는 경우라면 아래와 같은 for loop 문으로 콜 하게 될 것이다.

소스보기
 




결국 Connection은 100개가 생성되고, 100개가 반환되는 작업이 일어난다. 역시나 시스템 자원운용 면에서 보면 상당한 문제점을 야기시키는 부분일 것이다.

따라서 이와같이 타 세션빈에서 호출하는 메소드일 경우, DB 래퍼와 통신시에 Connection 객체를 넘겼듯 세션빈 메소드와 통신시에 Connection을 넘겨서 사용하는 패턴으로 가야 할 것이다.

위의 전표생성메소드를 Connection을 받아서 작업하는 메소드로 고쳐서 설계해보자. 물론 이 Connection을 생성시키고 닫아주는 주체는 전표생성 메소드를 콜한 세션빈이 하게 된다. 그렇다면 아래 소스처럼 regSlip 메소드를 오버로딩 한 메소드를 추가로 개발한다.

소스보기
 



이러한 메소드가 추가되면 먼저 만들어 두었던 regSlip 메소드는 아래와 같이 regSlip(Connection conn , SlipInfo[] sInfos)를 호출하자. 실제 비즈니스 프로세스는 regSlip(Connection conn , SlipInfo[] sInfos)안에 모두 있으므로, 이 메소드를 기존 그대로 놔두면 중복코드가 있게 된다.

소스보기
 




이와 같이 세션빈 메소드는 다른 세션빈 메소드가 업무상 호출할 수 있는 경우가 빈번하므로, 세션빈 메소드를 Connection 받는 것과 안 받는 것으로 오버로딩하는 패턴을 사용하게 된다.

세션빈 메소드는 다수 쿼리를 실행시키는 집합체
EJB 기반 프로젝트의 가장 큰 영역은 세션빈이다. 세션빈 내에서 모든 비즈니스 프로세스가 구현되므로, 세션빈 안에서 기타 클래스들을 어떠한 패턴으로 사용할 지 고민하며 설계하고 구현해야 재사용성이 높고 강력한 모듈을 만들 수 있다.

다음 강의에서는 실제 업무에서 일어나는 복잡한 프로세스를 구현함에 있어서 DBMS의 펑션이나 프로시져를 사용하는 것의 장점을 살펴보도록 하겠다.

2회까지는 세션빈 사용에 있어서의 클래스 패턴과, 시스템 성능 측면에서 어떤 점을 피해가야 하는지가 주된 논점이었다. 실제 프로젝트에서는 이 정도로 대부분의 이슈가 커버되겠지만, 막상 구현 결과물을 보면 세션빈 메소드가 수많은 쿼리를 실행시키는 집합체로 보인다.

그렇다면 이것을 단 한 번의 실행으로 끝내버리는 방법은 없을까. 다음 강의에서 그 방법에 대해 논의해보자. @  


http://www.zdnet.co.kr/techupdate/lectu ··· 2C00.htm
"Java" 카테고리의 다른 글
  • EJB 기반 프로젝트 수행 가이드 ④ (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ③ (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ② (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ① (0)2007/05/18
  • MIDI Sound 생성하기 (0)2007/05/18
2007/05/18 11:22 2007/05/18 11:22
Posted by webdizen
Tags EJB, Java, 메소드 오버로딩, 세션빈, 컨테이너, 트랜잭션
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/2993

Leave your greetings.

[로그인][오픈아이디란?]

Programming/Java2007/05/18 11:19

EJB 기반 프로젝트 수행 가이드 ①

세션빈에서의 DB 접근전략 및 엔터티빈 사용시 주의사항

김주현 (ERP 개발자)  
2004/03/16

① 세션빈에서의 DB 접근전략 및 엔터티빈 사용시 주의사항
② 세션빈에서의 트랜잭션 관리
③ 비즈니스 프로세스 구현 최적화하기
④ 능률 높여주는 유틸리티를 사용하자

EJB 아키텍처를 기반으로 웹애플리케이션을 구축하는 프로젝트들이 2000년 이후부터 증가해왔음은 모두가 아는 사실. 더불어 EJB 관련 서적들도 다양하게 출판됐고, EJB를 사용하는 개발자들도 늘어나고 있다.

그러나 실제 EJB를 사용하면서 개발자들이 저지르기 쉬운 실수, 함정 등은 아직 서적에서는 친절히 안내되어 있지 않은 듯 하다. 이번 강좌의 목적은 흔히 개발자들이 스스로 잘 안다고 생각하는 것 때문에 빠질 수 있는 함정들을 미리 짚어봄으로써 그 함정이 초래할 혼란을 최소화하는데 있다.

강좌 중간중간 퍼포먼스를 고려한 팁이 언급될 수도 있고, 클래스 설계와 관련된 첨언도 들어갈 수 있다. 이 강좌의 목적이나 성격이 하나의 개념에 대한 순차적인 설명 형식은 아니므로 기본개념 설명을 건너뛰거나, 동시에 초보 자바 개발자도 알고 있는 사항에 대해 새삼 지적하는 경우도 있을 것이다.

자신에게 닥칠 수도 있는 문제를 미리 파악해 보고, 어떠한 방법으로 예방하고 해결해야하는지 살펴보도록 하자. 이번 강좌에서 언급될 예시에서 쓰는 EJB의 스펙은 1.1버전이고, DBMS는 오라클 8i이다.

DB와의 연결은 누가, 언제, 어떻게 할까?
EJB 애플리케이션이 DB와의 연결자원을 이용하는 방법은 2가지다.

첫째, ConnectionPool 을 이용하는 방법이 있다. EJB 서버가 형성하게 되는 ‘ConnectionPool’이라는 데이터 소스를 이용하는 방법이다. 임의의 비즈니스 프로세스를 담당하는 세션빈의 메소드 내에서 DB의 레코드를 써야할 경우, ConnectionPool에서 java.sql.Connetion 객체를 받아 쓰는 경우이다.

웹로직(weblogic), 웹스피어(websphere), JBOSS 등 다양한 업체들의 EJB 서버마다 기동시 ConnetionPool을 생성시킬 수 있는 기능을 제공한다. 기동시 읽어들이는 프로퍼티 파일에 DB의 URL, SID, user name, 패스워드, ConnectionPool의 name까지 사용자가 지정해야 한다.

아래는 웹로직 서버(버전 5.1)의 weblogic.properties 파일 내의 ConnetionPool 설정정보 부분이다.



# testPool
weblogic.JBDC.connectionPool.testPool=\
url=JBDC:oracle:thin:@123.4.5.67:portNumber:sid명,\
driver=oracle.JBDC.driver.OracleDriver,\
initialCapacity=1,\
maxCapacity=10,\
CapacityIncrement=2,\
allowShrinking=true,\
shrinkPeriodMins=15,\
props=user=user명;password=패스워드




이렇게 EJB 서버 기동시 미리 ConnectionPool을 만들게 되면 애플리케이션 운영중 발생하게 되는 DBMS 와의 빈번한 요청이 있을 때마다 JBDC 드라이버로 DB와 일일이 연결할 필요없이, 만들어진 ConnetionPool에서 Connetion을 꺼내 쓰고 다시 반환하므로 시스템 퍼포먼스 측면에서 월등히 효율적이다.

둘째, 엔터티빈을 활용하는 방법이다. 엔터티빈 중에서도 컨테이너가 퍼시스턴스를 관리해주는 CMP 엔터티빈을 EJB 서버에 배치해 쓰면 개발자 입장에서는 많은 부담을 덜 수 있기 때문에 대부분의 프로젝트에서 BMP 엔터티빈 보다는 CMP 엔터티빈을 사용한다.

엔터티빈 객체 하나는 DB의 하나의 테이블을 대표하며, 엔터티빈 객체가 갖고 있는 필드들은 해당 테이블의 컬럼과 매핑된다. 엔터티빈의 인스턴스는 DB의 임의의 레코드를 객체화한 것이다. 그러므로 엔터티빈의 인스턴스를 호출하여, get, create, set, remove 등의 메소드를 쓴다면, 직접 SQL문을 DB로 날리지 않아도 동일한 결과를 얻을 수 있다. insert 문 대신 create 메소드를 쓰면 되므로 코딩이 간결해진다. 더불어 SQL문에 익숙하지 않은 개발자라도 쉽게 쓸 수 있다는 장점이 있다.

그러나 엔터티빈의 이러한, 소위 장점이라고 하는 것들에 섣불리 현혹되지 않는 것이 좋다. EJB 프로젝트에서 발생하는 문제의 원인은 대부분 엔터티빈에 있다.

DB 핸들링 주체는 세션빈
DB에 어떻게 접근하든 비즈니스 프로세스를 담당하는 주체는 세션빈이다. 그리고 분석된 업무 흐름을 애플리케이션으로 구현할 때의 최소단위는 세션빈의 메소드이다.

예를 들어 급여계산 프로그램이 있다면 세션빈 내의 calcuratorPay(String empNo, String yyyyMm)라는 메소드가 있을 것이고, 복리후생비 신청 프로그램은 submitWelfare(String empNo, String date, ...)라는 메소드를 콜한다.

개발자는 세션빈의 메소드 안에서 적절히 저 두가지 방법을 활용해 DB의 레코드를 핸들링하게 된다. 엔터티빈 인스턴스가 DB의 레코드를 표현한다고 해도, 엄청나게 다양한 조건 및 함수 등이 담겨있는 select 문의 효과를 엔터티빈 인스턴스를 사용해서 자바 코딩으로 얻을 수 있겠는가? 없다.

따라서 그러한 다양한 조회를 할 필요가 있는 경우에는 ConnectionPool 에서 connection 객체를 하나 얻어와서 쓰게 된다. 뿐만 아니라 update, delete, insert 등에서도 pk 값으로만 조회해서 그 값을 변경, 삭제, 추가하는 경우보다 추가적인 제약이 따르는 경우가 많다.

결국 전체 시스템의 모든 세션빈이 connetion 객체를 쓰는 경우가 훨씬 많기 때문에, 모든 세션빈이 콜 할 수 있는 공통 모듈로 connectionPool 에서 connection 객체를 하나 뽑아 리턴해주는 클래스의 개발 필요사항이 발생한다. 이 클래스에는 getConnetion() 및 closeConnection() 메소드가 위치하게 될 것이다.

아래 예시에서 등장하게 되는 ConnManager라는 클래스는 이러한 역할을 하는 클래스다.

예시 소스코드를 보자. 사번을 통해 사원명을 조회하는 매우 간단한 메소드이다.





위의 예시에서 보듯이 세션빈 메소드 내에서는 Connection 객체를 가지고 와서 마지막에 닫고, 자신을 호출한 클라이언트에게 사원명을 전달하는 일만 하고 있다. 직접적으로 DB에 갖다오는 일은 EmpDB라는 클래스에게 맡긴다. 다양한 업무를 반영하는 세션빈 메소드 내에서는 이와 같은 패턴이 보다 효과적이고 간결하다.

그렇다면 EmpDB라는 클래스의 getEmpName 메소드를 살펴보자.





사번 테이블에서 사원 번호로 사원명을 리턴하는 메소드이다. 이 메소드 중에서 가장 주의깊게 봐야 할 부분은 PreparedStatement를 Statement interface 대신 사용한 부분이다. 조회성 쿼리를 DB에 던지고자 할 경우 아무 생각없이 Statement interface를 사용하는 개발자가 많은데, 이렇게 만들어서는 안된다.

꼭 PreparedStatement를 사용하자
Statement 인터페이스 보다는 PreparedStatement가 낫다. 사실 ‘좋다’ 정도가 아니라 ‘Statement를 쓰지 말고 PreparedStatement를 써야한다’고 말해도 될 정도다.

getEmpName의 메소드에서 PreparedStatement 대신 Statement의 executeQuery(String sql) 메소드를 사용해서 개발하면 어떤 일이 생기는지 알아보자.

인사업무 담당자가 사원 한 명씩 상세정보를 조회하고자 한다고 가정하자. 조회버튼을 누르면 사원번호로 getEmpName 메소드안에서 쿼리가 스트링으로 완성돼 Statement의 executeQuery(String sql) 메소드안의 SQL 값으로 들어간다. DB의 옵티마이저가 쿼리를 파싱, 실행하고, resultSet 리턴한다.

여기서 다음 사원을 조회하면? 사원번호만 다른, 그러나 방금전 조회시의 쿼리와 모두 같은 스트링이 던져진다. DB의 옵티마이저가 쿼리를 파싱, 실행한다.

계속 다른 사원을 조회하면? DB 입장에서는 조회조건만 다른 쿼리에 대해 파싱을 반복적으로 하고 있는 셈이고, 매번 파싱을 하고 결과값을 리턴해야 하기에 조회시 결과값 출력도 그만큼 늦어진다.

만일 이 시스템 전체가 Statement 인터페이스로 이뤄져 있고, 향후 시스템 성능 테스트에서도 이 부분이 발견되지 않는다면 어느날 갑자기 원인도 모르게 CPU 사용도가 올라가고 시스템 전체가 느려지는 현상이 발생하게 된다. 서버 관리자가 서버를 내렸다 올리겠지만 원인을 알 수 없으니 속이 편하진 않을 터.

나중에 다시 스트레스 테스트를 하고, 결국 파싱과 실행 수가 비슷하다는 사실이 발견된다. 책임은 개발자들에게 돌아간다.

Statement로 이뤄진 프로그램을 PreparedStatement로 바꾸라는 지시가 떨어지겠지만 이는 간단치 않은 일이다. Statement로 되어있는 프로그램을 그동안 copy & paste 해서 만든 프로그램이 몇 개인지 파악도 안되고, 파악이 되다 해도 바꾸는 작업은 쉽지 않다.

PreparedStatement는 주어진 쿼리를 미리 파싱을 해두기 때문에, 조회조건만 달라진 다른 쿼리가 들어오면 바로 실행만 시키게 된다. 시스템 성능 면에서 훨씬 더 효율적이다.

엔터티빈으로 접근한 row는 또 다른 Connetion 객체로 접근하지 말 것
세션빈에서 한 레코드에 대해 변경을 하는 작업을 엔터티빈으로 한다고 하고, 이때 요청사항으로 추가되는 어떤 컬럼에 대해 변경하는 부분이 늘어난다고 하자. 기존 소스는 아래와 같다. 아래 소스는 세션빈 내에서 사원발령이 났을 경우 발령 시작일자와 발령 마감일자를 변경하는 비즈니스 프로세스를 갖고 있다.






여기에서 사원발령정보를 변경하기 위해 엔터티빈 리모트 인터페이스의 setStartDt, setEndDt 메소드를 사용했다. 여기서 만일 사원발령정보를 낼 때 변경 일자도 기록하라는 요청사항이 추가될 경우, 이를 기존 소스에 추가하는 작업에서 엔터티빈을 사용하지 않고 Connection 객체를 만들어서 직접 SQL문을 던지는 형식으로 레코드의 한 컬럼 값을 변경시킨다고 가정해보자.






위의 소스를 보면 일견 아무런 문제가 없어 보인다. 컴파일도 잘 되고 실행시에 아무런 에러도 나지 않는다. 하지만 결과를 보면,

기존





를 타서, 레코드에 startDt와 endDt 컬럼 부분은 모두 원하는 데로 변경이 되었으나,






부분이 실행이 되었음에도 변경 일자 컬럼에는 아무런 변화가 없음을 알 수 있다.

엔터티빈의 인스턴스를 가지고 온 후부터 DB 레코드와 엔터티빈간의 동기화가 형성되고, 세션빈 메소드가 끝났을 때 DB에 결과를 쓰게 된다. 즉, 최종적으로 기록이 남는 것은 엔터티빈으로 작업한 결과이다. 중간에 새로 생긴 업데이트 세션은 그 작업은 성공한다 해도 DB에는 전혀 반영이 되지 않는 것이다.

이 소스를 보고 ‘그렇다면 모두 엔터티빈 메소드로 실행시키면 되지 왜 굳이 Connection 객체로 접근하는가'라는 의문이 들 수도 있다. 하지만 시스템을 오픈하고 나서 테이블에 컬럼을 추가해야 하는 경우가 업무적으로 반드시 생기게 된다. 그때 추가된 컬럼에 대해서는 엔터티빈안에 추가된 컬럼의 필드와 상응하는 변수를 추가하고 엔터티빈을 서버에 다시 배치해야 한다. 하지만 이 작업이 번거로우므로 추가된 컬럼에 한해서 SQL 쿼리로 간단히 핸들링하고자 하는 계획을 세우게 된다. 그럴때 위와 같은 경우가 생기게 되고, 한 row에 대해서 엔터티빈을 콜 할 때 엔터티빈 인스턴스와 DB가 동기화 된다는 것을 염두에 두지 못한 채 Connetion 객체를 써서 업데이트하는 하는 일도 생기는 것이다.

위의 소스는 모두 Connection 객체를 써서 해당 row의 컬럼을 변경 시키든지, 아니면 모두 엔터티빈 메소드를 쓰도록 변경해야 한다.

엔터티빈 사용을 지양하자
주위에서 진행되는 프로젝트들을 살펴보면 엔터티빈을 몰라서 쓰지않는 것이 아니라, 엔터티빈의 성질을 잘 알기 때문에 안쓰는 경우를 종종 보게된다.

엔터티빈의 이점이 몇가지 있다는 것은 분명하지만 개발자 입장에서는 쿼리로 간단히 대처를 할 수 있다는 측면에서 엔터티빈을 기피하게 된다.

한편 엔터티빈 말고 Connection 객체로 DB를 핸들링한다고 해서 트랜잭션이 언제나 완결되는가 하면 그것은 또 아니다. 분명 엔터티빈보다는 훨씬 더 강력하지만 예외도 있다. 다음 이어지는 강좌에서는 그에 해당하는 예제를 들고, 이를 피하려면 어떤 전략을 취해야 하는지 소개하도록 하겠다. @

http://www.zdnet.co.kr/techupdate/lectu ··· 2C00.htm
"Java" 카테고리의 다른 글
  • EJB 기반 프로젝트 수행 가이드 ③ (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ② (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ① (0)2007/05/18
  • MIDI Sound 생성하기 (0)2007/05/18
  • Java 성능개선을 위한 Programming 기법 (0)2007/05/18
2007/05/18 11:19 2007/05/18 11:19
Posted by webdizen
Tags EJB, Java, 엔터티빈
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/2992

Leave your greetings.

[로그인][오픈아이디란?]

«Prev  1  Next»

RSS HanRSS
Blog Image
webdizen
이 곳은 컴퓨터에 대해 연구하고, 공유하고, 소통하기 위한 연구실입니다. 개인적으로는 OLAP, Data Mining, Semantic Web, Data Modeling에 대해서 연구하고 있습니다.

Categories

전체 (2998)
Webdizen (134)
Life (6)
Diary (16)
Blog (9)
IDEA (1)
Travel (10)
Book (14)
Photo (7)
Movie (7)
Music (13)
Leisure Sports (10)
Funny (5)
Hardware (119)
Software (120)
Windows (5)
Unix & Linux (119)
Installation (4)
Kernel (10)
System (34)
Develop (22)
X-Window (0)
Applicaton (31)
Security (4)
Framework (2)
Hadoop (2)
Programming (805)
Algorithm & Data Structure (1)
Assembly (38)
UNIX/Linux C (95)
C++ (128)
STL (4)
Java (38)
Win32 API (92)
ATL/COM (44)
MFC (151)
.NET (26)
WCF/WPF (4)
C# (28)
Network Programming (17)
Database Programming (12)
OpenGL / DirectX (13)
Multimedia Programming (0)
Game Programming (21)
Parallel Distributed Progra... (0)
Reverse Engineering (0)
Debugging (9)
Python (1)
Ruby (1)
Ruby on Rails (1)
QT (4)
GTK (0)
JSP (0)
PHP (6)
ASP.NET (6)
ASP (3)
Development (28)
Useful Library (2)
Data Modeling (0)
Database (105)
Oracle (4)
MSSQL (41)
MySQL (2)
Data Warehouse (2)
Data Mining (3)
Network (66)
Web (78)
DHTML (4)
XHTML (1)
Javascript (1)
CSS (1)
AJAX (9)
XML (11)
Flex (1)
Silverlight (3)
Security (91)
DoS (1)
Kernel (10)
Scanning (3)
Sniffing (0)
Spoofing (4)
Overflow (28)
Web (11)
Shell (10)
Format String (14)
Window (2)
Embedded (70)
Multimedia (27)
Mobile (14)
Graphic (24)
Management (633)
Knowledge (581)
Hadoop (0)

Notice

  • 메타 블로그 사이트에 등록
  • 새해 맞이 블로그의 변화
  • 블로그 명칭 변경
  • 도메인(www.webdizen.net) 구...
  • TEXTCUBE 1.6.1로 업그레이드...

Tags

  • SQL Server 2005
  • Checker
  • 최적화
  • random
  • 수안이
  • Traffic
  • 도메인
  • SQL 주입
  • iostream.h
  • Text
  • 메타 데이터
  • Programmer
  • 프린트
  • Delegate
  • Event
  • Webdizen
  • 영어속독
  • Connection String
  • Threads
  • Thread Pooling

Recent Articles

  • ASCII Code의 CRLF 제거 방법.
  • Hadoop 에서 c++ API 이용시....
  • Ubuntu Linux에서 Hadoop 구....
  • 내 심장을 한껏 뛰게한 "국가....
  • 스타 스키마 데이터베이스 설....

Recent Comments

  • ■ 온라인카지노 ▶ http://L....
    asdf 11/21
  • 그리고 혹시 해외여행자보험....
    kim 11/05
  • ★★실제 바다게임장과 똑같....
    asdf 11/04
  • sbsyama.co.to← 짱5000만당....
    asdf 11/04
  • ♡KicaZ??o(???) 바카라사....
    fdsf3fass 11/03

Recent Trackbacks

  • 파일 열기/저장하기 CFileDialog.
    은마군의 나태블록 02/11
  • World IT Show 2008.
    상우 :: Oranzie's BLOG 2008
  • cvs서버 설치하기.
    3인3색 2008
  • 속속 공개되는 Google Chart....
    PHP와 Web 2.0 2007
  • 마방진을 구하는 프로그램.
    Oranzie's BLOG 3 2007

Archive

  • 2009/09 (3)
  • 2009/08 (1)
  • 2009/03 (1)
  • 2009/02 (9)
  • 2009/01 (13)

Calendar

«   2009/11   »
일 월 화 수 목 금 토
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          

Bookmarks

    • Administration
      • IIS.NET
      • NTFAQ
      • OS의 모든 것
      • 리눅스포털
    • Database
      • SQL Server Central
      • SQL Team
    • Development
      • .NET Heaven
      • ASP Alliance
      • ASP.NET 2.0
      • Bullog.net
      • C# Corner
      • C++ (C PlusPlus.com)
      • C++ Reference
      • CodeGuru
      • CodePlex
      • DebugLab
      • Dev Articles
      • Devpia
      • DotNet Junkies
      • DotNet Zone
      • Driver Online
      • GOSU.NET
      • HOONS 닷넷
      • Joinc 팀블로그
      • KOSR
      • MSDN Home Page
      • OSR Online
      • Sky.ph - 개발자 커뮤니...
      • TAEYO.NET
      • The Code Project
      • WindowsClient.net
      • 김상욱의 개발자 Side
      • 조인시 위키
    • Human Networks
      • belief21c's e-space
      • I think I can
      • Invisible Rover's Blog :D
      • Rodman®
      • ■ Feel So Good~! ■
      • 까만 나비
      • 나를 가꾸는 시간.
      • 나만의 즐거움~~!
      • 단녕
      • 상우 :: Oranzie's BLOG
    • Information Technology
      • Microsoft TechNet
      • 지디넷코리아 - 글로벌...
    • Security
      • FoundStone
      • milw0rm
      • NewOrder
      • OpenRCE
      • Phrack.org
      • Reverse Engineering b1...
      • Reverse Engineering Team
      • RootKit
      • SecurityFocus
      • SecurityXploded by Nag...
      • Wow Hacker
      • Zone-H
Textcube
Louice Studio Inc.
Powered by Textcube. Original designed by Tistory.