저번에 Beta2예제가 새로운 버전에서 안돌아가는 바람에 다시 만들었습니다-_-;
많은 분들이 안돌아간다고 하셔서 다시 만들었습니다 ㅠ
형식이 조금 바뀌었는데, 별 차이는 없었습니다.
더 편해진 것 같아요. 토큰이라는 것을 이용하네요.

http://code.google.com/p/assql/
다양한 예제와 lib파일은 이곳에서 받을 수 있습니다.

간단하게 insert와 select를 하는 예제를 만들어봤습니다.
테스트 해본 환경은 Eclpse3.4 + Flex Builder 3.0.1 + asSQL Beta 2.7에서 해봤습니다.

DB구조는 다음과 같습니다.

CREATE TABLE `products` (
`id` int(10) unsigned NOT NULL auto_increment,
`description` varchar(45) default NULL,
`price` decimal(15,2) NOT NULL default '0.00',
PRIMARY KEY USING BTREE (`id`,`price`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

INSERT INTO `products` (`id`,`description`,`price`) VALUES
(1,'Lamp','469.80'),
(2,'Table','3502.62'),
(3,'Chair','1061.12');


아래는 소스코드입니다.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="onCreationComplete()"
layout="horizontal">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import com.maclema.mysql.ResultSet;
import com.maclema.mysql.MySqlToken;
import com.maclema.mysql.Statement;
import com.maclema.mysql.Connection;
import com.maclema.mysql.events.MySqlErrorEvent;
import mx.rpc.AsyncResponder;
import mx.controls.Alert;

private var con:Connection;
private var st:Statement;
private var token:MySqlToken;
[Bindable]
private var dataAC:ArrayCollection;

private function onCreationComplete():void
{
con = new Connection("DB주소", 3306, "DB아이디", "DB비밀번호", "DB명");
con.addEventListener(Event.CONNECT, handleConnected);
con.connect("euckr");
}

private function handleConnected(e:Event):void
{
if (con != null)
{
st = con.createStatement();
}
}

private function selectResult(data:Object, token:Object):void
{
var rs:ResultSet = ResultSet(data);
dataAC = rs.getRows();
}

private function insertResult(data:Object, token:Object):void
{
Alert.show(token.description + " 삽입성공!");
selectProcess();
insertBox.visible = false;
}

private function fault(info:Object, token:Object):void
{
Alert.show("Error: " + info);
}

private function selectProcess():void
{
var token:MySqlToken = st.executeQuery(
"SELECT id, description, price FROM products");
token.addResponder(new AsyncResponder(selectResult, fault));
}

private function insertProcess():void
{
st.sql = "INSERT INTO products (description, price) VALUES (?, ?)";
st.setString(1, inputDescription.text);
st.setNumber(2, Number(inputPrice.text));
var token:MySqlToken = st.executeQuery();
token.description = inputDescription.text;
token.addResponder(new AsyncResponder(insertResult, fault, token));
}
]]>
</mx:Script>

<mx:VBox horizontalAlign="center">
<mx:DataGrid id="productDG" dataProvider="{dataAC}">
<mx:columns>
<mx:DataGridColumn headerText="ID" dataField="id"/>
<mx:DataGridColumn headerText="제품명" dataField="description"/>
<mx:DataGridColumn headerText="가격" dataField="price"/>
</mx:columns>
</mx:DataGrid>

<mx:HBox width="100%" horizontalAlign="center">
<mx:Button label="SELECT" id="btnSelect"
click="insertBox.visible = false; selectProcess()"/>
<mx:Button label="INSERT" id="btnInsert"
click="insertBox.visible = true"/>
</mx:HBox>

<mx:VBox id="insertBox" height="100%" horizontalAlign="center" visible="false">
<mx:Form>
<mx:FormHeading label="정보 입력" />
<mx:FormItem label="제품명">
<mx:TextInput id="inputDescription" />
</mx:FormItem>
<mx:FormItem label="가격">
<mx:TextInput id="inputPrice" restrict="0-9,."/>
</mx:FormItem>
</mx:Form>
<mx:Button id="btnInsertProcess" label="추가" click="insertProcess()" />
</mx:VBox>

</mx:VBox>

</mx:Application>

좀 이상한 점이 con.connect("euckr")로 해야지 한글이 나오더군요. mysql에서 utf8에는 한글이 없는건가.
어쨌든 인코딩은 어려워요 ㅠ

Connection이라는 클래스를 통해 mysql정보를 이용해 con객체를 생성한다음에 Statement를 생성합니다.
그 뒤에 selectProcess메소드에서 보시면, MySqlToken이라는 클래스를 이용합니다. Statement객체의 executeQuery메소드에 쿼리문을 넣어서 실행하면 token이 발행됩니다.
이 token에 addResponder라는 메소드를 통해 AsyncResponder를 이용해 해당 function넣은 객체를 생성해서 addResponder에 집어넣습니다. 그러면 데이터를 가져오는 시점에서 넣은 function이 호출이 됩니다.

여기서 데이터를 파싱하는 부분에서 엄청 편해진 부분이있는데요.
rs.getRows();

getRows라는 메소드가 있는데, 이건 해당 데이터셋을 자동으로 ArrayCollection형으로 변환해서 리턴해줍니다.
그러면 바로 바인딩된 datagrid에 데이터가 뿌려지겠죠. 멋집니다.

insert부분도 똑같습니다.
그냥 자바문법과 비슷하다고 보면 되겠네요.
틀린 점이 있다면 이건 이벤트기반이라는 것이죠 ^^ 비동기적으로 일어납니다.
사용자 삽입 이미지

셀렉트도 잘되네요. 구글크롬에서 해봤어요. 잘 되네요.

사용자 삽입 이미지

머드초보를 2.00로 해서 입력해봅시다.

사용자 삽입 이미지

잘 들어갔네요.

PS. 실무db연동은....서버단언어와 함께하시길 바랍니다 ^^ (JAVA, C# 등등~)
머드초보 이 작성.

당신의 의견을 작성해 주세요.

  1. Comment RSS : http://mudchobo.tomeii.com/tt/rss/comment/318
  2. 지돌스타 2008/09/03 15:35  편집/삭제  댓글 작성  댓글 주소

    좋은 정보입니다. ^^

    • 머드초보 2008/09/03 19:00  편집/삭제  댓글 주소

      보니까 asSQL버전이 올라가면서 기존 예제가 문제가 있었더라구요.
      코딩방식이 바뀌어서 다시 만들었습니다 ^^
      방문해주셔서 감사해요~ ^^
      그....기존 버전의 트랙백을 날려주셔도 돼요 ^^

  3. keril 2008/09/03 19:09  편집/삭제  댓글 작성  댓글 주소

    말씀해주신대로 mysql설정미스인듯합니다..

    그런데 잘 해결이 안되고있네요 ^^;

  4. keril 2008/09/03 19:13  편집/삭제  댓글 작성  댓글 주소

    그리고 이클립스 유로파 (eclipse-jee-europa-winter-win32) 가 실행이 안되네요
    제껏만 그런가해서 친구컴에서도 해봤는데 같은 증상....
    jvm terminated. Exit code=-1 로시작해서 꽤나긴 설명이있는데 짧은지식으로는 ㅋ

  5. 비매품 2008/09/03 22:09  편집/삭제  댓글 작성  댓글 주소

    아;; 제가 정말 초보라 그러는데;;
    굳이 이클립스가 필요한건가요? 코딩은 플렉스3 빌더에서 다 할 수 있는거 아닌가요? ㅠㅠ;

    그리고 돌려보니까...
    insert에 품목 입력하면

    Error #2044: 처리되지 않은 ioError입니다. text=Error #2031: 소켓 오류입니다. URL: DB주소

    Main Thread (Suspended: TypeError: Error #1009: null 객체 참조의 속성이나 메서드에 액세스할 수 없습니다.)
    FlexMysqlTest/insertProcess
    FlexMysqlTest/__btnInsertProcess_click

    이렇게 뜨는데 제가 뭘 빼먹은건지 궁금합니다.^^;;;;;

    • 머드초보 2008/09/04 09:03  편집/삭제  댓글 주소

      이클립스는 자바프로그래밍을 위해서 필요합니다.
      Flex는 RemoteObject를 통해서 완벽하게 java연동을 지원합니다.
      그래서 DB연동은 JAVA단에서 주로 하는데, 이것을 하려면
      이클립스가 필요합니다.

      그리고 소켓오류는 제 위에 소스를 그대로 가져다가 쓰신 것 같은데요.
      저기 DB주소부분에는 DB주소가 들어가야합니다.
      localhost나 DB서버가 작동하고 있는 서버의 IP를 적어주시면 돼요 ^^
      그리고 포트는 디폴트로 설치하셨으면 1521이고,
      DB접속ID, PW, 그리고 DB명을 넣어주시는 겁니다.

  6. 비매품 2008/09/04 09:55  편집/삭제  댓글 작성  댓글 주소

    asSQL이 자바나 php없이도 연결가능하다 그래서 이클립스가 필요없는줄 알았습니다 ^^;;
    소스 다시보니까 제가 아무것도 안하고 그냥 돌리기만 했네요 ^^;;;
    디비 공부좀 많이 해야겠습니다.ㅠㅠ 디비가 완전 꽉막혀서;;

    답글 고맙습니다^^

    • 머드초보 2008/09/04 10:11  편집/삭제  댓글 주소

      asSQL은 자바나 PHP없이 DB연결이 가능합니다.
      asSQL를 이용해서 DB연동한다면 이클립스가 필요없습니다.
      asSQL은 클라이언트에서 직접 MySQL에 접속하여 DB를 제어합니다.
      하지만, 보안상 취약점도 있고, DAO단을 따로 만드는게
      나중에 유지보수차원에서 더 좋을듯싶습니다.
      간단한 DB연동이라면 asSQL을 쓰셔도 될 듯 합니다 ^^

  7. atom 2008/09/08 10:11  편집/삭제  댓글 작성  댓글 주소

    안녕하세요.. 머드 초보님..

    위의 포스트를 보고 flex를 이용하여 웹에 붙이는걸 했습니다.

    하지만 에러가 나던데..ㅠㅠ 이유를 잘 몰라서 이렇게 물어 보게 되네요..

    -------------------------------------------------------------
    Error #2044: 처리되지 않은 ioError입니다. text=Error #2048: 보안 샌드박스 문제가 발생했습니다. http://210.118.69.241/Web_Service_Test/bin-debug/Web_Service_Test.swf은(는) 210.118.69.241:3306에서 데이터를 로드할 수 없습니다.
    --------------------------------------------------------------

    에러 메세지는 위와 같은데.. 이리저리 사방 팔방 물어 보고 해봐도 답이 안나오네요..

    flex builder에서 실행 하였을 때는 잘 되는데... 이걸 웹페이지에 embed로 붙여서 사용하니 바로 에러발생하네요..

    이것 땜시 3일째 잠을 못자고 있는데.. 너무 답답한 마음에.. 물어 보게 되네요..ㅠ

    • 머드초보 2008/09/08 11:23  편집/삭제  댓글 주소

      보안샌드박스 문제입니다.
      MySQL서버가 돌아가는 서버에 crossdomain.xml파일이 있어야합니다.
      이것에 swf파일이 돌아가는 서버가 MySQL이 설치된 서버에 허락이 되어있는지가 정의된 파일입니다.
      http://code.google.com/p/assql/wiki/JavaPolicyFileServer
      이게 서버프로그램인데 요걸 컴파일해서 MySQL이 설치된 서버에 띄워놓으시면 될겁니다.
      사실 저도 안해봐서-_-; 잠만 해볼께요-_-;

      아...해보니까 되네요 ^^
      저걸 서블릿으로 띄우는데 저 띄우는게
      843포트를 열어서 보안파일을 전송하는 듯합니다.
      궁금한거있으면 메일주세요.
      mudchobo@nate.com

  8. 꽃녀 2008/09/08 11:41  편집/삭제  댓글 작성  댓글 주소

    헐..좋은정보입니다.

    저도 따라서 한번 해봐야겠네요.~~

  9. atom 2008/09/08 13:19  편집/삭제  댓글 작성  댓글 주소

    머드초보님이 링크 걸어 주신 곳으로 들어가서 xml이랑 파일을 만들었는데.. 컴파일 해서 그냥 켜놓으라는 이야기인가요??ㅋ

    • 머드초보 2008/09/08 13:27  편집/삭제  댓글 주소

      컴파일해서 톰캣으로 띄우는겁니다.
      톰캣이 뜨면서 저 프로그램로직상 843포트를 열어놓게 되는데
      이 포트를 이용해서 클라이언트가 보안파일을 요청하는데
      보안파일에 허용되는 도메인이면
      허용할 수 있게 하는겁니다.

      즉, 톰캣의 $CATALINA_HOME$/webapps/ROOT/WEB-INF/classes에 저 컴파일한게 들어가고, web.xml에는 저기 설정에 맞는 서블릿 설정이 들어가면 되겠죠 ^^

      c로 된 것도 예전에 있었는데요.
      이 놈은 cygwin을 이용해서 gcc로 컴파일해서 그냥 띄워놓으면 되는겁니다.

  10. 꽃녀 2008/09/08 13:56  편집/삭제  댓글 작성  댓글 주소

    그러니깐..

    저위의 예는 서버사이드(JAVA, PHP)없이 ASSQL을 사용한 예이구요..

    실제 개발할때는 ASSQL을 사용하지 않고 Remoting 등으로

    서버사이드를 거쳐 (일반적인 방식으로..) 사용하라는 말인거죠? ^^;

    저도 헷갈리고 사람들도 헷갈릴거 같아서 ㅋ;;

    • 머드초보 2008/09/08 14:23  편집/삭제  댓글 주소

      아넵 맞습니다 ^^
      아직 asSQL이 보안상 문제가 좀 있다고 합니다-_-;
      그리고, DAO단은....따로 빼는게 편한 ^^
      그냥 저 예제는 저 정도가 가능하다는 것을 그냥 보여준거죠 ^^

  11. 네버다이 2008/09/12 14:04  편집/삭제  댓글 작성  댓글 주소

    머드초보님 잘 지내셨는지요? ^^

    assql 찾다가 또 머드초보님 홈피로 왔네요.

    위 예제 따라해보고 있는데요. 로컬은 잘되나 제 홈피계정에서 돌리면 위에서 이미 언급하신분처럼

    에러가 나네요. crossdomain.xml 설정해줬구요.

    http://otl.pe.kr/a/assql.html

    위 페이지입니다.

    호스팅업체에서는 localhost호스트에 대해서 따로 막지는 않았다고 합니다. 포트도 기본포트구요.

    문제가 뭘까요? 그럼 추석 잘 보내세요~


    <?xml version="1.0"?>
    <cross-domain-policy>
    <allow-access-from domain="*" to-ports="3306" secure="false" />
    <allow-access-from domain="*.otl.pe.kr" to-ports="3306" secure="false" />
    <allow-access-from domain="www.otl.pe.kr" to-ports="3306" secure="false" />
    <allow-access-from domain="otl.pe.kr" to-ports="3306" secure="false" />
    </cross-domain-policy>

    • 머드초보 2008/09/12 14:18  편집/삭제  댓글 주소

      안녕하세요~
      assql은 http통신이 아닌 소켓으로 3306포트로 직접 통신하고 있습니다.
      그래서 3306포트로 소켓을 연결할 때 FLEX애플리케이션은 843포트로 크로스도메인파일을 요청합니다.
      그래서 843포트로 크로스도메인파일을 줄 서버프로그램을 만들어야합니다.
      http://code.google.com/p/assql/wiki/JavaPolicyFileServer
      이거대로 톰캣으로 띄워서 843포트를 여시는 방법이 있구요.
      서버가 유닉스나 리눅스 계열이라면 gcc를 이용한 방법이 있습니다.
      http://panzergruppe.hp.infoseek.co.jp/fspfd.html
      그리고 assql은 localhost로 하면 안되더라구요.
      아이피를 직접 써주셔야합니다.
      해당 MySQL서버의 아이피를 직접 써주셔야합니다 ^^

      그나저나 네버다이님 오랜만이네요 ^^

  12. 네버다이 2008/09/12 14:42  편집/삭제  댓글 작성  댓글 주소

    네 오래간만이네요. 오기는 자주왔는데 글을 안써서리.. ^^

    제가 호스팅을 받다보니 제약이 많네요.

    우선 linux서버에 apache,php,mysql 연동된 호스팅받고 있구요.

    업체쪽에서 뭔가 해주지지는 않을꺼 같네요. 이거 되면 홈피에 이거저거 만들어 볼라고 했더만

    843번만이라도 열어달라고 하면될라나... ^^

    ip를 직접써줘야 한다는건 결국 연동했을때 공인ip를 가진 mysql일 경우만 가능한 경우가 되겠군요.

    • 머드초보 2008/09/12 14:53  편집/삭제  댓글 주소

      아 그렇군요.
      843번포트로 서버프로그램만 띄울 수 있다면 됩니다 ^^
      ip말고 도메인으로 해도 될것같은데요.
      mysql이 떠있는 서버의 아이피나, 도메인주소를 알면 되는것이죠^^
      호스팅을 받고 있군요.
      음 샤바샤바만 잘해보시면 ^^

  13. 돌아이비 2008/11/12 12:07  편집/삭제  댓글 작성  댓글 주소

    안녕하세요? 플렉스를 공부하고 있는 초보 프로그래머입니다.^^
    asSQL 관련예제를 검색하다가 머드초보님 블로그를 방문하게 되었는데 플렉스 관련 예제가 많네요~
    머드초보님 예제들로 열공해야겠습니다. 좋은 예제들 감사해요~^^

    • 머드초보 2008/11/15 10:41  편집/삭제  댓글 주소

      저도 초보 프로그래머입니다 ㅠㅠ
      허접한 예제가 도움이 되었으면 합니다 ^^

  14. 돌아이비 2008/11/13 00:02  편집/삭제  댓글 작성  댓글 주소

    예제 받아간지 얼마되지 않아서 바로 질문을 드리게 되네요..^^;;
    #2048 보안샌드박스 문제가 발생하길래 댓글로 알려주신 페이지에 있는 소스들 참고해서
    web.xml / crossdomain.xml / PolicyServerServlet.java 3개 파일을 만들었습니다.

    web.xml은 $CATALINA_HOME$/webapps/ROOT/WEB-INF 내의 web.xml 파일에 내용 추가했고,

    crossdomain.xml 파일은 $CATALINA_HOME$/webapps/ROOT 폴더 내에 두었고요.

    PolicyServerServlet.java 파일은 javac로 컴파일해서
    PolicyServerServlet.class / PolicyServerServlet$1.class / PolicyServerServlet$1$1.class 3개 파일을
    $CATALINA_HOME$/webapps/ROOT/WEB-INF/classes/com/maclema/flash 폴더 내에 넣었습니다.

    그런데도 디버그 모드로 띄워보니

    오류: http://localhost:8080/lcds/assql-ex-debug/main.swf의 SWF는 정책 파일 없이 해당 도메인에서 소켓에 연결할 수 없습니다.

    라는 오류메시지가 뜨네요..ㅠ_ㅠ

    의심가는 부분은 PolicyServerSevlet.java 파일 내 crossdomain.xml 파일 경로 설정 부분 뿐인데..
    어떻게 해야 보안샌드박스 문제를 해결할 수 있을지 도저히 감이 안와서 이렇게 댓글을 남깁니다.

    그럼 즐거운 하루 보내시고 시간 여유있으실 때 답변 부탁드려요^^ 굽신굽신~

    • 머드초보 2008/11/15 10:44  편집/삭제  댓글 주소

      음...우선 정책파일을 못 찾는 것 같은데....
      서블릿에서 생성하는 놈은 843포트로 정책파일을 받는 스레드를
      만드는 겁니다. assql은 소켓을 통해 db내용을 송수신 하기 때문입니다.
      타 도메인에 있는 소켓을 사용하려면 정책파일에 허락이 되어있는지
      정의가 되어있어야 하는데요.
      위는 뭔가 셋팅이 잘못 된 듯 합니다.
      결론은 저...저도 잘모르겠습니다 ㅠㅠ

  15. 돌아이비 2008/11/17 07:32  편집/삭제  댓글 작성  댓글 주소

    음.. 그렇군요.. ㅠ_ㅠ
    여기저기 검색하면서 이렇게 저렇게 고쳐봤는데도 여전히 먹통이네요.. ㅠ_ㅠ
    그래도 로컬에서는 잘 돌아가니까 공부하는데는 별 지장이 없네요~
    정책파일 문제는.. 다 그렇듯이 언젠가는 해결법을 찾겠죠^^;
    답변 감사드려요~ 즐거운 하루 보내세요^^

    • 머드초보 2008/11/19 14:11  편집/삭제  댓글 주소

      음....보안샌드박스문제는 생각해보면 간단합니다.
      해당 서버에서 해당 도메인을 허락하는거죠 ^^
      좀만 더 보시면 알 수 있을겁니다^^

  16. EH71 2008/11/19 12:46  편집/삭제  댓글 작성  댓글 주소

    안녕하세요-
    흔적도 없이 포스팅 잘 보고 있습니다ㅎㅎㅎ

    오늘은 흔적을 좀 남겨야 할 것 같은데요....
    책들을 참조해서 자바 서버 애플리케이션 <-> 플렉스 클라이언트 채팅 프로그램을 만들어보고 있는데요.
    서버는 톰캣에 얹어 돌리는 서블릿은 아니고 소켓이 구현되어 있는 통짜 애플리케이션입니다.

    플렉스 클라이언트에서 접속을 시도하면 보안 샌드박스 에러가 나는데요.
    이 포스트에 써주신 같은 방법으로 이 문제를 해결할 수 있는건지 궁금합니다.
    클라이언트는 80포트로 html 파일에 접근해서, 8401포트로 자바 애플리케이션에 접근합니다.

    이 포스트에 있는 방법을 수정해서 적용해야 한다면 어떤 부분을 수정해주어야 하나요?

    답변 주시면 감사드리겠습니다ㅠ 초보에겐 너무 어렵네요ㅠㅠ

    • 머드초보 2008/11/19 14:12  편집/삭제  댓글 주소

      안녕하세요!
      구조가 어떻게 되어있는지 이해가 잘 안되네요 ㅠ
      클라이언트가 80포트로 html에 접근하다니 무슨 말인지 모르겠어요.

http://mudchobo.tomeii.com/tt/257 에 이어서-_-;

오라클에서 해보겠습니다.
아 우선 오라클용 jdbc가 필요해요!
ojdbc6.jar 등의 jbdc ^^

걍 오라클용 dataSource로 바꿔주면 돼요-_-;

applicationContext.xml


<!-- oracle용 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="oracle.jdbc.driver.OracleDriver"
p:url="jdbc:oracle:thin:@localhost:1521:XE"
p:username="dbid" p:password="dbpw" />

<bean id="insertDataOracle" class="com.mudchobo.TestInsertOracle"
p:sqlMapClient-ref="sqlMapClient"/>

아까 그 TestInsert 인터페이스입니다.
TestInsert.java

package com.mudchobo;

import org.springframework.transaction.annotation.Transactional;

public interface TestInsert {

@Transactional(readOnly=true, rollbackFor={Throwable.class})
public void insertData() throws Throwable;

}

저기 선언된 bean인 TestInsertOracle을 구현해봅시다.
TestInsertOracle.java

package com.mudchobo;

import java.io.IOException;

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

public class TestInsertOracle extends SqlMapClientDaoSupport implements
TestInsert {

@Override
public void insertData() throws Throwable {
getSqlMapClientTemplate().insert("insertData");
System.out.println("oracle에 insert성공");
throw new IOException();
}
}

MySQL처럼 IOException을 임의로 발생시킵니다.
main부분을 봅시다.
TestTransaction.java

package com.mudchobo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestTransaction {

public static void main(String[] args) {
String[] configLocation = {"applicationContext.xml"};
ApplicationContext context =
new ClassPathXmlApplicationContext(configLocation);

TestInsert testInsertOracle =
(TestInsert) context.getBean("insertDataOracle");

try {
testInsertOracle.insertData();
} catch (Throwable e) {
System.out.println("예외발생");
}
}
}

오라클에서는 readOnly로 걸어 놨는데도 불구하고 insert가 됩니다.
그리고 예외를 발생시켰기 때문에 rollbackfor 값을 Throwable로 줬기때문에 IOException이 발생했을 때 롤백하게 됩니다. 잘보면 롤백이 되어있습니다.

오라클에서 set transaction read only 라고 쿼리를 날리면 transaction을 read only로 해버릴 수 있더라구요.
뭐 그냥 그렇다구요-_-;

머드초보 이 작성.

당신의 의견을 작성해 주세요.

스프링에서 제공하는 트랜젝션을 MySQL과 Oracle에다가 적용을 해봤습니다.
제가 잘 이해를 못하는 건지 모르겠는데, Oracle에서는 ReadOnly가 안먹혀요-_-;
MySQL에서는 먹히는데....-_-; Oracle에서는 자체적으로 transaction에서 ReadOnly를 설정하는게 있더군요.
또 Oracle은 트랜젝션기반이라고 하더라구요. 암튼, 참 어렵습니다-_-;
우선 삽질한 코드입니다.
MySQL로 해보았습니다.

필요한 lib입니다.
spring.jar - 스프링할껀데 필요하겠죠?-_-;
commons-logging.jar - 스프링하려면 이눔이 있어야 돼요-_-; 위에 있는 lib와 종속돼요-_-;
ibatis-2.3.0.677.jar - ibatis로 할껍니다. 이게 db연동을 쉽게 해주니까요-_-;
mysql-connector-java-5.1.5-bin.jar - mysql connector가 필요하겠죠!

프로젝트를 만듭시다. TestTransaction이라는 프로젝트를 만듭시다.
최상위 src폴더에다가 applicationContext.xml파일을 만듭시다.

applicationContext.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<tx:annotation-driven />

<!-- MySQL용 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://db주소"
p:username="dbid" p:password="dbpw" />

<!-- Transaction manager for iBATIS Daos -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />

<!-- SqlMap setup for iBATIS Database Layer -->
<bean id="sqlMapClient"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"
p:dataSource-ref="dataSource"
p:configLocation="classpath:SqlMapConfig.xml" />

<bean id="insertDataMysql" class="com.mudchobo.TestInsertMysql"
p:sqlMapClient-ref="sqlMapClient"/>
</beans>

TestInsert라는 interface를 작성해봅시다.
TestInsert.java

package com.mudchobo;

import org.springframework.transaction.annotation.Transactional;

public interface TestInsert {

@Transactional(readOnly=true, rollbackFor={Throwable.class})
public void insertData() throws Throwable;
}

인터페이스에다가 트랜젝션을 걸어도 되더라구요-_-; 구현되는 모든놈이 저 옵션으로 트랜젝션이 먹히는 듯 합니다. 근데 별로 안좋은 방법인듯한데-_-; 그냥 메소드에 거는게.....-_-; 보면 readOnly옵션에다가 Throwable예외가 발생하면 롤백합니다.

구현해봅시다.
TestInsertMysql.java

package com.mudchobo;

import java.io.IOException;

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

public class TestInsertMysql extends SqlMapClientDaoSupport implements
TestInsert {

@Override
public void insertData() throws Throwable {
getSqlMapClientTemplate().insert("insertData");
System.out.println("mysql에 insert성공");
throw new IOException();
}
}

insert를 시키고, 강제로 IOException을 발생시켰습니다.

ibatis xml부분을 봅시다.
SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
<sqlMap resource="Insert.xml" />
</sqlMapConfig>

Insert.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Sqlmap">
<insert id="insertData">
insert into TESTDATA (DATA) values ('MUDCHOBO')
</insert>
</sqlMap>

보시면 단순 insert를 하고 있습니다-_-;

main부분입니다.
TestTransaction.java

package com.mudchobo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestTransaction {
public static void main(String[] args) throws Throwable{
String[] configLocation = {"applicationContext.xml"};
ApplicationContext context =
new ClassPathXmlApplicationContext(configLocation);

TestInsert testInsertMysql =
(TestInsert) context.getBean("insertData");
try {
testInsertMysql.insertData();
} catch (Throwable e) {
System.out.println("예외발생");
}
}

이걸 실행하면 트랜젝션이 readOnly이기 때문에 insert하려고 하면 에러가 나버리겠죠.
Connection is read-only. Queries leading to data modification are not allowed; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:
요런 에러를 보실 수 있습니다.

Oracle은 다음 장에서-_-;
http://mudchobo.tomeii.com/tt/258 여기에 계속-_-;

머드초보 이 작성.

당신의 의견을 작성해 주세요.

« Prev : 1 : 2 : 3 : Next »