인메모리 데이터베이스 VoltDB의 트랜잭션 처리를 시도해 보기
VoltDB 트랜잭션 처리
인메모리 데이터베이스인 VoltDB는 NoSQL에 비해 빠르고(또는 넘어), NoSQL에서는 실현이 어려운 트랜잭션 처리(ACID)를 실현할 수 있습니다.
VoltDB는 DML(insert/update/delete/select)을 Java로 구현된 저장 프로시저로 구현합니다. 저장 프로시저를 시작하면 VoltDB는 자동으로 트랜잭션을 시작하고 저장 프로시저가 완료되면 자동으로 커밋됩니다. 저장 프로 시저가 오류 등으로 완료되지 않으면 자동으로 롤백됩니다 (원자).
명시적으로 VoltAbortException 예외를 throw 하는 것으로, 강제적으로 롤백 할 수도 있습니다.
프로 시저 작성
실제로 트랜잭션 처리를 확인해 보겠습니다.
다음 처리를 수행하는 프로시저를 작성하십시오.
(1) 거래를 시작한다. (자동)
(2) A 테이블에 삽입한다.
(3) B 테이블에 삽입한다.
(4) 커밋한다. (자동)
에러시에 롤백하는 것을 확인하기 위해, (2)와 (3)의 사이에 예외를 발생시킵니다.
먼저 테스트용 테이블(TEST_A, TEST_B)을 만듭니다.
$ sqlcmd
CREATE TABLE TEST_A (
ID varchar(50) NOT NULL,
DATA smallint,
PRIMARY KEY (ID)
);
PARTITION TABLE TEST_A ON COLUMN ID;
CREATE TABLE TEST_B (
ID varchar(50) NOT NULL,
DATA smallint,
PRIMARY KEY (ID)
);
PARTITION TABLE TEST_B ON COLUMN ID;
그런 다음 다음 두 가지 저장 프로시저를 만듭니다.
· InsertDataToAAndB : 테이블 A와 테이블 B에 삽입합니다.
· InsertDataToAAndBFail : InsertDataToAAndB를 유용하고 예외를 추가.
InsertDataToAAndB.javapackage test;
import org.voltdb.SQLStmt;
import org.voltdb.VoltProcedure;
public class InsertDataToAAndB extends VoltProcedure {
public final SQLStmt insertTestA = new SQLStmt("insert into test_a values(?, ?)");
public final SQLStmt insertTestB = new SQLStmt("insert into test_b values(?, ?)");
public long run(String idA, int dataA, String idB, int dataB) throws VoltAbortException {
voltQueueSQL(insertTestA, idA, dataA);
voltExecuteSQL();
//InsertDataToAAndBFailクラスの場合はここで例外をスローしている。
voltQueueSQL(insertTestB, idB, dataB);
voltExecuteSQL();
return 2L;
}
}
작성한 프로시저는 컴파일하고 catalog.jar을 작성합니다.
VoltDB 서버에 방금 만든 catalog.jar을 업로드하고 다음 명령으로 프로시저를 로드합니다.
$ sqlcmd 3
1> load classes catalog.jar;
2> show classes;
--- Potential Procedure Classes ------------------------------
test.InsertDataToAAndB
test.InsertDataToAAndBFail
"Potential Procedure Classes"에서 프로시저가 로드되었음을 알 수 있습니다.
그런 다음 프로시저를 작성(정의)하기 위해 다음 명령을 실행하십시오.
두 프로시저가 "Active Procedure Classes"가 됩니다.
$ sqlcmd
1> CREATE PROCEDURE FROM CLASS test.InsertDataToAAndB;
2> CREATE PROCEDURE FROM CLASS test.InsertDataToAAndBFail;
--- Active Procedure Classes ---------------------------------
test.InsertDataToAAndB
test.InsertDataToAAndBFail
만든 프로시저를 실행하여 트랜잭션 처리를 확인합니다.
InsertDataToAAndB를 호출하여 TEST_A 및 TEST_B 테이블에 한 레코드씩 삽입합니다.
$ sqlcmd
> exec InsertDataToAAndB "1" 100 "1" 200;
(Returned 2 rows in 0.00s)
TEST_A, TEST_B 테이블에 한 레코드씩 삽입되어 있는지 확인합니다.
> select * from test_a;
ID DATA
---- -----
"1" 100
(Returned 1 rows in 0.01s)
> select * from test_b;
ID DATA
---- -----
"1" 200
(Returned 1 rows in 0.00s)
다음에 TEST_A에 삽입 후, 예외를 발생시켜 롤백시킨 경우를 확인합니다.
> exec InsertDataToAAndBFail "2" 100 "2" 200;
VOLTDB ERROR: USER ABORT
test exception
at test.InsertDataToAAndBFail.run(InsertDataToAAndBFail.java:16)
예외 발생으로 롤백되어, TEST_A, TEST_B 테이블에는 원래부터 존재한 1 레코드 밖에 없는 것을 확인할 수 있습니다.
> select * from test_a;
ID DATA
---- -----
"1" 100
(Returned 1 rows in 0.00s)
> select * from test_b;
ID DATA
---- -----
"1" 200
(Returned 1 rows in 0.00s)
끝에
VoltDB에서 트랜잭션 처리가 가능하다는 것을 확인했습니다.
트랜잭션 처리는 가능했지만, 복수 테이블을 갱신할 때에 파티션 키를 지정하는 방법을 모른다. 이번 방법이라면 멀티 파티션이 되어 버려 성능이 떨어진다 (라고 생각된다). 그것이 사양인지 설정·코딩이 나쁜지는 조사해 볼 필요가 있습니다.
덧붙여 스토어드 프로시저의 실행 계획은 이하와 같이 되어 있어, 「RECEIVE FROM ALL PARTITIONS SEND PARTITION RESULTS TO COORDINATOR」로부터, 멀티 파티션으로 처리되고 있으므로 틀림없을 것 같습니다.
Reference
이 문제에 관하여(인메모리 데이터베이스 VoltDB의 트랜잭션 처리를 시도해 보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/mkyz08/items/3e548e864a86409c28ec
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
실제로 트랜잭션 처리를 확인해 보겠습니다.
다음 처리를 수행하는 프로시저를 작성하십시오.
(1) 거래를 시작한다. (자동)
(2) A 테이블에 삽입한다.
(3) B 테이블에 삽입한다.
(4) 커밋한다. (자동)
에러시에 롤백하는 것을 확인하기 위해, (2)와 (3)의 사이에 예외를 발생시킵니다.
먼저 테스트용 테이블(TEST_A, TEST_B)을 만듭니다.
$ sqlcmd
CREATE TABLE TEST_A (
ID varchar(50) NOT NULL,
DATA smallint,
PRIMARY KEY (ID)
);
PARTITION TABLE TEST_A ON COLUMN ID;
CREATE TABLE TEST_B (
ID varchar(50) NOT NULL,
DATA smallint,
PRIMARY KEY (ID)
);
PARTITION TABLE TEST_B ON COLUMN ID;
그런 다음 다음 두 가지 저장 프로시저를 만듭니다.
· InsertDataToAAndB : 테이블 A와 테이블 B에 삽입합니다.
· InsertDataToAAndBFail : InsertDataToAAndB를 유용하고 예외를 추가.
InsertDataToAAndB.java
package test;
import org.voltdb.SQLStmt;
import org.voltdb.VoltProcedure;
public class InsertDataToAAndB extends VoltProcedure {
public final SQLStmt insertTestA = new SQLStmt("insert into test_a values(?, ?)");
public final SQLStmt insertTestB = new SQLStmt("insert into test_b values(?, ?)");
public long run(String idA, int dataA, String idB, int dataB) throws VoltAbortException {
voltQueueSQL(insertTestA, idA, dataA);
voltExecuteSQL();
//InsertDataToAAndBFailクラスの場合はここで例外をスローしている。
voltQueueSQL(insertTestB, idB, dataB);
voltExecuteSQL();
return 2L;
}
}
작성한 프로시저는 컴파일하고 catalog.jar을 작성합니다.
VoltDB 서버에 방금 만든 catalog.jar을 업로드하고 다음 명령으로 프로시저를 로드합니다.
$ sqlcmd 3
1> load classes catalog.jar;
2> show classes;
--- Potential Procedure Classes ------------------------------
test.InsertDataToAAndB
test.InsertDataToAAndBFail
"Potential Procedure Classes"에서 프로시저가 로드되었음을 알 수 있습니다.
그런 다음 프로시저를 작성(정의)하기 위해 다음 명령을 실행하십시오.
두 프로시저가 "Active Procedure Classes"가 됩니다.
$ sqlcmd
1> CREATE PROCEDURE FROM CLASS test.InsertDataToAAndB;
2> CREATE PROCEDURE FROM CLASS test.InsertDataToAAndBFail;
--- Active Procedure Classes ---------------------------------
test.InsertDataToAAndB
test.InsertDataToAAndBFail
만든 프로시저를 실행하여 트랜잭션 처리를 확인합니다.
InsertDataToAAndB를 호출하여 TEST_A 및 TEST_B 테이블에 한 레코드씩 삽입합니다.
$ sqlcmd
> exec InsertDataToAAndB "1" 100 "1" 200;
(Returned 2 rows in 0.00s)
TEST_A, TEST_B 테이블에 한 레코드씩 삽입되어 있는지 확인합니다.
> select * from test_a;
ID DATA
---- -----
"1" 100
(Returned 1 rows in 0.01s)
> select * from test_b;
ID DATA
---- -----
"1" 200
(Returned 1 rows in 0.00s)
다음에 TEST_A에 삽입 후, 예외를 발생시켜 롤백시킨 경우를 확인합니다.
> exec InsertDataToAAndBFail "2" 100 "2" 200;
VOLTDB ERROR: USER ABORT
test exception
at test.InsertDataToAAndBFail.run(InsertDataToAAndBFail.java:16)
예외 발생으로 롤백되어, TEST_A, TEST_B 테이블에는 원래부터 존재한 1 레코드 밖에 없는 것을 확인할 수 있습니다.
> select * from test_a;
ID DATA
---- -----
"1" 100
(Returned 1 rows in 0.00s)
> select * from test_b;
ID DATA
---- -----
"1" 200
(Returned 1 rows in 0.00s)
끝에
VoltDB에서 트랜잭션 처리가 가능하다는 것을 확인했습니다.
트랜잭션 처리는 가능했지만, 복수 테이블을 갱신할 때에 파티션 키를 지정하는 방법을 모른다. 이번 방법이라면 멀티 파티션이 되어 버려 성능이 떨어진다 (라고 생각된다). 그것이 사양인지 설정·코딩이 나쁜지는 조사해 볼 필요가 있습니다.
덧붙여 스토어드 프로시저의 실행 계획은 이하와 같이 되어 있어, 「RECEIVE FROM ALL PARTITIONS SEND PARTITION RESULTS TO COORDINATOR」로부터, 멀티 파티션으로 처리되고 있으므로 틀림없을 것 같습니다.
Reference
이 문제에 관하여(인메모리 데이터베이스 VoltDB의 트랜잭션 처리를 시도해 보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/mkyz08/items/3e548e864a86409c28ec
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(인메모리 데이터베이스 VoltDB의 트랜잭션 처리를 시도해 보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/mkyz08/items/3e548e864a86409c28ec텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)