이제 Couchbase Server 7.0은 N1QL 트랜잭션을 지원합니다.
단일 노드에서 일련의 트랜잭션을 수행하는 C 프로그램을 작성해 보겠습니다.
1단계: 먼저 프로그램을 호출하는 방법을 결정합니다. 입력값은 쿼리를 실행하려는 Couchbase 버킷의 URL과 자격 증명(사용자 이름과 비밀번호)입니다.
사용법:|
1 |
./n1ql couchbase://localhost/test Administrator password |
N1QL 트랜잭션의 경우, START TRANSACTION 명령에서 txid 값이 반환됩니다. 이 값은 최종 COMMIT 또는 ROLLBACK까지 트랜잭션 내의 모든 후속 N1QL 쿼리에 사용됩니다. 따라서 트랜잭션의 일부인 나머지 쿼리 요청에 전달할 수 있는 트랜잭션 ID를 메인 함수에서 선언해야 합니다.
2단계: 트랜잭션 시작 쿼리에서 트랜잭션 ID를 저장하는 데 사용할 포인터를 초기화합니다. 이 ID는 전체 트랜잭션에서 사용됩니다.
|
1 |
char *transaction_id = (char *)malloc(64 * sizeof(char)); |
3단계: 클러스터 초기화
카우치베이스 서버 클러스터에 대한 연결은 다음과 같이 표시됩니다. lcb_INSTANCE 객체입니다.
lcb_INSTANCE *인스턴스;
허용되는 작업 집합은 이 개체의 유형과 버킷이 이 개체에 연결되어 있는지 여부에 따라 달라집니다. 여기서는 Cluster 유형을 사용합니다. 클러스터 객체를 만드는 가장 간단한 방법은 lcb_create 를 전달하여 카우치베이스 핸들을 생성하려면 lcb_type_cluster 에 연결 문자열, 사용자 이름, 비밀번호를 입력합니다. 다음으로 lcb_connect()를 사용하여 연결을 예약한 다음 버킷이 존재하는지 확인합니다.
|
1 2 3 4 5 6 7 8 9 |
lcb_CREATEOPTS *create_options = NULL; lcb_createopts_create(&create_options, LCB_TYPE_CLUSTER); lcb_createopts_connstr(create_options, argv[1], strlen(argv[1])); lcb_createopts_credentials(create_options, argv[2], strlen(argv[2]), argv[3], strlen(argv[3])); check(lcb_create(&instance, create_options), "create couchbase handle"); lcb_createopts_destroy(create_options); check(lcb_connect(instance), "schedule connection"); lcb_wait(instance, LCB_WAIT_DEFAULT); check(lcb_cntl(instance, LCB_CNTL_GET, LCB_CNTL_BUCKETNAME, &bucket), "get bucket name"); |
4단계: query.h에서 쿼리 실행
쿼리.h에 트랜잭션에 해당하는 쿼리가 정의되어 있습니다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
BEGIN WORK INSERT INTO test VALUES(\"kkk1\", {\"a\":1}) SELECT d.*, META(d).id FROM test AS d WHERE d.a >= 0 SAVEPOINT s1 UPDATE test AS d SET d.b = 10 WHERE d.a > 0 SELECT d.*, META(d).id FROM test AS d WHERE d.a >= 0 SAVEPOINT s2 UPDATE test AS d SET d.b = 10, d.c = \"xyz\" WHERE d.a > 0 SELECT d.*, META(d).id FROM test AS d WHERE d.a >= 0 ROLLBACK TRAN TO SAVEPOINT s2 SELECT d.*, META(d).id FROM test AS d WHERE d.a >= 0 INSERT INTO test VALUES(\"kkk2\", {\"a\":2}) UPDATE test AS d SET d.b = 20, d.c = \"xyz\" WHERE d.a > 0 COMMIT WORK |
트랜잭션 ID를 추출하기 위해 쿼리 결과를 처리하기 위해 C언어의 JSON 파싱 라이브러리를 사용해야 합니다. 여기서는 json-c 라이브러리를 사용할 수 있습니다. BEGIN WORK 문(첫 번째 문)에서 트랜잭션 ID를 가져오기 위해 txid 콜백 함수를 사용합니다. 다른 쿼리를 처리하고 실행하기 위해 행 콜백 함수를 호출합니다. 그러면 결과 행이 반환됩니다.
|
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 |
for> (ii = >0>; ii < num_queries; ii++) {> >lcb_CMDQUERY> *>cmd>; > >lcb_cmdquery_create>(&cmd);> >check>(lcb_cmdquery_statement(cmd, queries[ii].query, strlen(queries[ii].query)), >"set QUERY statement">);> >printf>(>"----> \x1b[1m%s\x1b[0m\n">, queries[ii].query);> >if> (ii == >0>) {> >lcb_cmdquery_callback>(cmd, txid_callback);> >lcb_wait>(instance, LCB_WAIT_DEFAULT);> >check>(lcb_query(instance, transaction_id, cmd), >"schedule QUERY operation">);> >lcb_wait>(instance, LCB_WAIT_DEFAULT); > } >else> {> >char> buf>[100];> >sprintf>(buf,>"\">%s\>"">,transaction_id);> >lcb_cmdquery_callback>(cmd, row_callback);> >// SET rest option pretty to true and txtimeout to 3s> >check>(lcb_cmdquery_option(cmd, >"pretty">, strlen(>"pretty">), >"true">, strlen(>"true">)),>"set QUERY 'pretty' option">);> >check>(lcb_cmdquery_option(cmd, >"txtimeout">, strlen(>"txtimeout">), >"\">3s>\>"">, strlen(>"\">3s>\>"">)),>"set QUERY 'txtimeout' option">);> check(lcb_cmdquery_option(cmd, >"txid">, >strlen>(>"txid">),buf, >strlen>(buf)),>"set QUERY 'txtimeout' option">);> check(lcb_query(instance, >NULL>, cmd), >"schedule QUERY operation">);> lcb_wait(instance, LCB_WAIT_DEFAULT);> } > lcb_cmdquery_destroy(cmd);> lcb_wait(instance, LCB_WAIT_DEFAULT);> }> |
쿼리를 실행하기 전에 pretty, txtimeout(트랜잭션 시간 초과), 첫 번째 문에서 가져온 txid라는 세 가지 쿼리 매개 변수를 설정했습니다. 이는 요청 수준 매개변수입니다.
이제 콜백 함수에 대해 자세히 알아보겠습니다.
Txid_Callback -
여기서는 BEGIN WORK 문을 실행한 JSON 응답을 파싱하여 JSONC 라이브러리를 사용하여 후속 문에 쿼리 파라미터로 전달할 txid를 추출해야 합니다. 이를 위해 이전에 생성한 포인터를 사용하여 lcb_respquery_cookie 메서드에 설정합니다. 이렇게 하면 연산 쿠키가 설정됩니다. 즉, lcb_query를 실행할 때 쿠키 인수가 있고 lcb_respquery_cookie는 콜백 함수에서 이 포인터를 가져옵니다. (메인 함수에서 포인터를 생성하고 콜백 함수에서 설정했습니다.)
|
1 2 3 4 5 6 7 8 9 10 |
/* create pointer transaction_id and set it in the callback */ lcb_respquery_cookie(resp, (void **)&transaction_id); check(lcb_respquery_status(resp),"check response status"); lcb_respquery_row(resp, &row, &nrow); if (!lcb_respquery_is_final(resp)) { parsed_json = json_tokener_parse(row); json_object_object_get_ex(parsed_json, "txid", &txid_obj); temp = json_object_get_string(txid_obj); strcpy(transaction_id,temp); } |
행 콜백 - 쿼리 실행에서 결과 행을 구문 분석하고 검색하는 데 사용됩니다.
|
1 2 3 4 5 6 7 8 9 |
lcb_STATUS rc = lcb_respquery_status(resp); lcb_respquery_row(resp, &row, &nrow); ln2space(row, nrow); fprintf(stderr, "[\x1b[%dmQUERY\x1b[0m] %s, (%d) %.*s\n", err2color(rc), lcb_strerror_short(rc), (int)nrow, (int)nrow, row); if (lcb_respquery_is_final(resp)) { fprintf(stderr, "\n"); } } |
여기에서 쿼리 응답을 가져와서 행을 가져와서 인쇄합니다.
위의 예제를 사용하여 이제 C SDK에서 N1QL 트랜잭션을 사용할 수 있습니다. 전체 코드와 실행 방법에 대한 지침은 다음을 참조하세요. https://github.com/ikandaswamy/CBSDK_N1QLExamples