hibernateでハマった。

try {

if(isMappingDataExists(deleteEntity)) {
new hoge1Dao().deleteByCategoryId(deleteEntity);
}
hoge2Dao.delete(deleteEntity);
trans.commit();

} catch(Exception e) {
trans.rollback();
e.printStackTrace();
} finally {
hibernateSession.close();
}


こんな感じの記述でひとつのトランザクション内で2つのテーブルを削除した時mysqlで

Lock wait timeout exceeded; try restarting transaction

なんてエラーが出たのでmysqlでロックが起きてしまって先に進めずタイムアウトしたと判断。
2つのテーブルが親子関係だったのもあり、外部キーが悪いのではないかとずっと疑いハマった。

定かではないが、原因はDaoをnewするときにhibernateとmysqlのコネクションの独立したものが2つ発生していて、競合してしまったようだ。

try {

if(isMappingDataExists(deleteEntity)) {
new hoge1Dao(hibernateSession).deleteByCategoryId(deleteEntity);
}
hoge2Dao.delete(deleteEntity);
trans.commit();

}

こんな感じでセッションを使いまわすことで解決。




・・・基本ですよね。。。


対処法

① javascriptでformのAction属性を書き換える

② dispatchActionを使う

③ lookupActionを使う

②、③はstruts-configがとActionクラスを変える必要があるし、

そもそも処理毎にActionクラスを用意している場合には、使わない方がよさそう。

①なら外部のjsファイルに、formのidとパスを引数にしたfunction一つ持たせるだけで良い。


一つの画面で一つのアクションと捉えるか、一つのボタンで一つのアクションと捉えるかの違いな気がする。

①の方がサーバ側のコードが読みやすくなるし、調べてみるとこっちの方が一般的ならしいので、

以降は①の方法でいこう。


javascriptが使えない環境の場合は、②、③かな。