2014년 12월 26일 금요일

[Sails.js 0.10.5] sailsjs에서 transaction

ORM layer transaction

이 기능은 현재 개발중인 기능으로. 현재 버전인 0.10.5버전에서는 아직 구현이 되지 않은 부분이다. 0.11.x버전 즈음에서 한차례 기능 테스트를 하고, 0.12.x에서 인터페이스를 다듬어서 릴리스 할 예정이라는거 같다.

처음 아래 투고를 보고 당연히 지금 기능을 하는 내용인줄 알았는데 0.10.5기준에서는 그런 기능이 없다고 에러를 뱉어왔다.

https://github.com/balderdashy/waterline/issues/62

그리고 아래에서 다음 작업내용들이 정리되어있다.

https://github.com/balderdashy/sails-docs/blob/master/contributing/roadmap.md

ORM layer transaction이 구현되고 나면, transaction을 통상 지원하지 않는 다른 데이터베이스에서도 동일한 효과를 얻을 수 있지 않을까 하고 기대해본다.

MySQL transaction.

현재 ORM layer에서 transaction을 지원하지 않는다 하여 손을 놓고 있을 순 없는 일이다.
한정적이나마, MySQL에서의 transaction사용법을 체크하고 넘어가볼까 한다.

조금 조사해봤지만, ORM자체에 의존한채로 query를 날리는 방법으로는 transaction이 동작하지 않았다. 커뮤니티에 떠도는 소스중에

Model.query("BEGIN");
...
Model.query([some sql to insert, update, etc...]) ...
...
Model.query("ROLLBACK" or "COMMIT");

과 같은 형태로 써보라는 말이 있긴했는데, 위와 같은 구성으로 query를 날렸을시, mysql측에서 받기로는 다음과 같은 느낌이었다.

  52 Query BEGIN
  53 Query INSERT INTO `dummy` (`name`, `createdAt`, `updatedAt`) values ('0.0907773447688669', '2014-12-26 15:15:12', '2014-12-26 15:15:12')

  52 Query ROLLBACK

가장 좌측에 보이는 52, 53은 query시의 connection id를 나타내는 수치인데 BEGIN과 INSERT의 id가 다른것을 알 수 있다. ORM딴에선 별도 커넥션으로 접속해버리는듯 하다.
문서화가 진행중인 부분에다가, 공식적으론 아직 서포트 하지 않는 상태라, 다른 기술자들의 의견교환 정도밖에 문서가 보이지 않고 있었는데, 공식 위키에는 다음과 같은 내용이 있었다.

https://github.com/balderdashy/sails-mysql/wiki/Transactions

2012년의 좀 오래된 기록이긴 하지만, 결국에 0.10.5의 현 시점에서는 직접적으로 mysql모듈을 통해서 쿼리를 날리란 내용이었다.

0.11.x(현재 git의 unstable)에서는 ORM을 통해서도 transaction을 이용하게 된다고 하니, 그때까지는 상기의 문서에서 이야기하는 내용으로 transaction을 이용할 수 밖에 없는듯 하다.

상기 코드를 참고로 구성한 코드에서는 이하와 같이 동작확인이 가능했다.

  68 Connect sails@localhost on sails
  68 Query BEGIN;
  68 Query INSERT INTO `dummy` (`name`, `createdAt`, `updatedAt`) values ('0.1618976395111531', '2014-12-26 15:15:12', '2014-12-26 15:15:12')
  68 Query COMMIT
  68 Quit

이하에 테스트 코드를 첨부한다.

var math = require("mathjs");
var mysql = require('mysql');  

// ...  

var connectionConfig = sails.config.connections.mysql;  
var connection = mysql.createConnection({  
   host : connectionConfig.host,
   user : connectionConfig.user,
   password : connectionConfig.password,
   database : connectionConfig.database,
   multipleStatements: true,
});  


 connection.connect(function(err) {  
   connection.query(  
     "BEGIN;"+
     "INSERT INTO `dummy` (`name`, `createdAt`, `updatedAt`) values ('"+math.random().toString()+"', '2014-12-26 15:15:12', '2014-12-26 15:15:12')",  
     function(err,rows,fields) {  
     if(err)  
     {  
       sails.log.error(err);
       connection.query("ROLLBACK;");
     }  
     else
     {  
       connection.query("COMMIT;");
     }  
     connection.end();
     res.json("finish with : "+err);  
   });  
 });  

댓글 없음:

댓글 쓰기