S_a_k_Uの日記みたいなDB

~サクゥーと呼ばないで~

排他制御のロックとコネクションの切断と

もうね、わけワカメですわ(笑
複数のコネクション(AとBとX)でDBにアクセスし、同じテーブルに対して操作してみた。
(丸番号は下記のソース参照)
■基本的な流れ
①コネクションXでcreate table文とinsert文を実行して、コネクションXをcommit、closeする。
②コネクションAでselect文を実行する(【X】WITHOUT LOCK)。
④コネクションBでselect文を実行する(【X】WITHOUT LOCK)。
⑦コネクションAでdrop table文を実行すると、排他制御で止まる。


■お試しでやってみた流れ
・⑤コネクションBをcommitしても、⑦コネクションAのdrop table文で排他制御で止まったまま。
・⑥コネクションBをcloseすると、⑦コネクションAのdrop table文が実行される。しかし、③コネクションAをcommitしていないと、エラーとなる。

KFPA11935-E Unable to execute definition SQL for executing data processing SQL[PrdbPreparedStatement.execute][HiRDB_CONNECTION_ID(sds01:1605:6816)])

・select文を【Y】WITH EXCLUSIVE LOCKでロックしている場合、2つのコネクションで排他ができており、③ロックしたコネクションAがcommitすれば、④待ちのコネクションBのselect文が実行される。
・コネクションXをcloseしないと、⑦コネクションAのdrop table文で排他制御で止まったまま。
後はテストコードで試して下さいw



select文でWITHOUT LOCKとして、commitした後に、HiRDBコマンド「pdls -d lck -a」ってしてみたらなんか占有したままっぽいwww
コネクションをcloseしないと、drop tableできないって普通なん???



プーリングといい、なんか今まで通りに使えん(爆



感覚的に、定義系SQLを実行する場合は、アクセスしたコネクションがcloseされないとダメっぽいって動きに見える。



いろいろお試しに使ったテストコード

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties;

public class DbTest {
    
    public static void main(String [] args) {
        Properties userInfo = new Properties();
        userInfo.put("user", "hoge");
        userInfo.put("password", "hoge");
	String jbdcDrv = "JP.co.Hitachi.soft.HiRDB.JDBC.HiRDBDriver";
        String url = "jdbc:hitachi:hirdb://DB=HiRDB,DBID=22200,DBHOST=xxx.xxx.xxx.xxx";
        Connection conA = null;
        Connection conB = null;
        Connection conX = null;
        try {    
            Class.forName(jbdcDrv);
            conA = DriverManager.getConnection(url, userInfo);
            conB = DriverManager.getConnection(url, userInfo); 
            conX = DriverManager.getConnection(url, userInfo); 
            conA.setAutoCommit(false);
            conB.setAutoCommit(false);
            conX.setAutoCommit(false);
            try {
                dropTable(conX);
            } catch (Throwable t) {
                // nothing
            }  
            createTable(conX);  //①
            conX.commit();
            conX.close();
            selectTable(conA);  //②
            //conA.commit();    //③
            selectTable(conB);  //④
            //conB.commit();    //⑤
            //conB.close();     //⑥
            dropTable(conA);    //⑦
        } catch (Throwable t) {
            t.printStackTrace();
        }     
    }
    
    private static void dropTable(Connection con) throws SQLException {
        String sql = "DROP TABLE test_t";
        PreparedStatement stmt = con.prepareStatement(sql);
        stmt.execute();
    }
    
    private static void createTable(Connection con) throws SQLException {        
        String sql = "CREATE TABLE test_t (col_a CHAR(3), col_b CHAR(3)) IN (RDDATA10) PRIMARY KEY (col_a) IN (RDINDX10)";
        PreparedStatement stmt = con.prepareStatement(sql);
        stmt.execute();
        String insertSql = "INSERT INTO test_t (col_a, col_b) values ('xxx', 'yyy')";
        PreparedStatement insertStmt = con.prepareStatement(insertSql);
        insertStmt.executeUpdate();
    }
    
    private static void selectTable(Connection con) throws SQLException {    
        String sql = "SELECT * FROM test_t WITHOUT LOCK";           //【X】
        //String sql = "SELECT * FROM test_t WITH EXCLUSIVE LOCK";  //【Y】
        PreparedStatement stmt = con.prepareStatement(sql);
        ResultSet rs = stmt.executeQuery();
        while (rs.next()) {
            System.out.println(rs.getString(1) + rs.getString(2));
        }
    }
    
}