소개: 타 DBMS에서 SELECT 문을 통해 row level lock을 거는 방법으로 사용되는 SELECT ~ FOR UPDATE 구문이 CUBRID에는 존재하지 않는다. 이를 대체하는 방법으로 CUBRID 확장 JDBC API인 setWriteLock를 소개한다.
적용 대상: CUBRID2008R1.x 이상, JDK1.5이상
SELECT ~ FOR UPDATE 대체 방법
타 DBMS에서 SELECT 문을 통해 특정 row에 lock을 거는 문장으로 사용되는 것이 SELECT ~ FOR UPDATE 구문이다. 사용 예는 아래와 같다.
SELECT * FROM code where s_name=’X’ FOR UPDATE;
CUBRID에서는 위 구문을 지원하지 않는다. 이를 대체하기 위해서 CUBRID 확장 JDBC API인 setWriteLock를 제공하고 있다.
구문은
void setWriteLock()
로 CUBRIDOID 클래스에 포함된 메소드 이다.
setWriteLock 예제
아래는 setWriteLock을 사용하는 예제로 code 테이블의 s_name이 ‘X’인 row를 조회하면서 쓰기 잠금을 설정한 후 해당 row의 f_name을 ‘XXX’로 update 시키는 예제이다.
import java.sql.*;
import cubrid.sql.*; //1
public class TestWriteLock1{
public static void main(String arg[]) throws Exception {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
Class.forName("cubrid.jdbc.driver.CUBRIDDriver");
conn = DriverManager.getConnection("jdbc:cubrid:localhost:39000:demodb:::","","");
conn.setAutoCommit(false); //2
Object result = null;
String sbQuery = "SELECT class(a), a.* FROM code a WHERE a.s_name=?"; //3
String s_name = "X";
String f_name = "XXX";
ps = conn.prepareStatement(sbQuery);
ps.setString(1, s_name);
rs = ps.executeQuery();
if(rs.next()) {
result = rs.getObject(1); //4
CUBRIDOID oid = (CUBRIDOID)result; //5
oid.setWriteLock(); //6
if(ps != null) ps.close();
ps = conn.prepareStatement("UPDATE code SET f_name = ? WHERE CLASS(code) = ?"); //7
ps.setString(1, f_name);
ps.setObject(2, result); //8
ps.executeUpdate();
}
if(rs != null) rs.close();
if(ps != null) ps.close();
conn.commit();
}catch ( SQLException e ) {
conn.rollback();
e.printStackTrace();
} catch(Exception e) {
conn.rollback();
e.printStackTrace();
} finally {
if(rs != null) rs.close();
if(ps != null) ps.close();
if(conn != null) conn.close();
}
}
}
· 1 : setWriteLock는 CUBRIDOID의 메소드로 CUBRIDOID를 사용하기 위해서는 cubrid.sql.*를 import 해야한다.
· 2 : 동일 트랜잭션 내에서 select 후 update를 수행하여야 하므로 autoCommit을 false로 설정한다.
· 3 : 해당 row의 OID를 가져오기 위해서는 SELECT 문에 class(table_name) 형식으로 명시해준다. 위 예제는 code 테이블의 alias를 a로 부여 하였기 때문에 class(a)와 같이 명시 하였다.
· 4, 5 : 조회된 OID는 getObject() 를 사용하여 Object 형태로 받은 후, CUBRIDOID로 형변환을 수행한다.
· 6 : CUBRIDOID.setWriteLock()를 호출하여 해당 row를 쓰기 잠금 설정한다.
· 7 : 쓰기 잠금 설정된 row의 데이터를 update하기 위해서 비교 조건으로 위에서 받아온 OID를 사용한다. OID를 조회 조건으로 사용하기 위해서는 class(table_name) 형식으로 명시해준다.
· 8 : OID 값을 해당 위치에 바인딩 하기 위해서는 setObject()를 사용한다.