S2JDBC DB2DialectでのforUpdate()を調べてみた

FOR UPDATEの自動生成

DB2Dialectを指定してS2JDBCSQL自動生成でforUpdate()を使うと、「 for update with rs」が付加されたSQLが発行されます。

select T1_.KEY as C1_, T1_.VALUE as C2_ from ID_GENERATOR T1_ where T1_.KEY = 'EMPLOYEE_ID' for update with rs

Db2Dialectのソースをのぞいてみると、そのような記述があるのが確認できます。ちなみにDb2DialectはS2Tigerの中に存在します。

利用できないメソッド

  • forUpdateNowait()
  • forUpdateNowait(CharSequence... propertyNames)
  • forUpdateWait(int seconds)
  • forUpdateWait(int seconds, CharSequence... propertyNames)

これらのメソッドはDB2では利用できません。UnsupportedOperationExceptionとともに、「DBMS(db2)ではサポートされていません。」というメッセージが表示されます。

  • forUpdate(CharSequence... propertyNames)

カラムを指定したforUpdateメソッドも利用できません。ただ、「FOR UPDATE OF ...」という構文がDB2にはあります。もしかしたら実際はできるのでは。そんなわけで、他のDialectを参考にしたりして少しいじってみることに。

脱線の結果

で、なんとなくわかったこと。どうやらテーブル名のエイリアスが指定されているとダメなようです。「FOR UPDATE OF」以降をカラム名のみで組み立てるようにしたら、とりあえず通るようにはなりました。

ただ、テーブル結合を伴う場合についても考慮する必要がありますし、そもそもDB2と他のDBMSとでは異なる挙動になっているのかもしれません。自動生成に関しては、素直にカラム指定なしのforUpdate()を使っておくのがいいと思います。

いちおういじってみたコードを載せておきます。

public class MyDb2Dialect extends Db2Dialect {
    @Override
    public boolean supportsForUpdate(final SelectForUpdateType type,
            boolean withTarget) {
        return type == SelectForUpdateType.NORMAL;
    }

    @Override
    public String getForUpdateString(final SelectForUpdateType type,
            final int waitSeconds, final Pair<String, String>... aliases) {
        final StringBuilder buf = new StringBuilder(100).append(" for update");
        if (aliases.length > 0) {
            buf.append(" of ");
            for (final Pair<String, String> alias : aliases) {
                buf.append(alias.getSecond()).append(", ");
            }
            buf.setLength(buf.length() - 2);
        }
        buf.append(" with rs");
        return new String(buf);
    }
}

関連記事:

DB2で「SELECT ... FOR UPDATE」のロックを検証 - 130単位

原文地址:https://www.cnblogs.com/aggavara/p/2708718.html