FOR UPDATEの自動生成
DB2Dialectを指定してS2JDBCのSQL自動生成で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); } }
関連記事: