1

私の Web アプリケーションでは、とのパフォーマンスを向上させるためにStateless sessionswithを使用しています。Hibernateinsertsupdates

(開発モードのプレイフレームワークH2 databaseで使用されるもの)で正常に動作していました。

しかし、私がそれをテストするとMySQL、次の例外が発生します:

ERROR ~ Lock wait timeout exceeded; try restarting transaction
ERROR ~ HHH000315: Exception executing batch [Lock wait timeout exceeded; try restarting transaction]

コードは次のとおりです。

public static void update() {
    Session session = (Session) JPA.em().getDelegate();
    StatelessSession stateless = this.session.getSessionFactory().openStatelessSession();

        try {

            stateless.beginTransaction();

            // Fetch all products
            {
                List<ProductType> list = ProductType.retrieveAllWithHistory();
                for (ProductType pt : list) {
                    updatePrice(pt, stateless);
                }
            }

            // Fetch all raw materials
            {
                List<RawMaterialType> list = RawMaterialType.retrieveAllWithHistory();
                for (RawMaterialType rm : list) {
                    updatePrice(rm, stateless);
                }
            }
        } catch (Exception ex) {
            play.Logger.error(ex.getMessage());
            ExceptionLog.log(ex, Thread.currentThread());
        } finally {
            stateless.getTransaction().commit();
            stateless.close();
        }
}

private static void updatePrice(ProductType pt, StatelessSession stateless) {
    pt.priceDelta = computeDelta();
    pt.unitPrice = computePrice();

    stateless.update(pt);

    PriceHistory ph = new PriceHistory(pt, price);

    stateless.insert(ph);
}

private static void updatePrice(RawMaterialType rm, StatelessSession stateless) {
    rm.priceDelta = computeDelta();
    rm.unitPrice = computePrice();

    stateless.update(rm);

    PriceHistory ph = new GoodPriceHistory(rm, price);

    stateless.insert(ph);
}

この例では、3 つの単純なエンティティ( ProductTypeRawMaterialTypeおよびPriceHistory) があります。 computeDeltaDBのcomputePriceものを含まない単なるアルゴリズム関数です。 retrieveAllWithHistory関数は、関数を使用してデータベースからデータをフェッチするPlay framework model関数です。

したがって、このコードはデータを取得し、編集し、新しいデータを作成して、最後にすべてを保存します。

でロック例外がMySQLあり、で例外がないのはなぜH2ですか?

4

1 に答える 1

0

finallyブロックにコミットがある理由がわかりません。この構造を試してみてください:

try {
    factory.getCurrentSession().beginTransaction();
    factory.getCurrentSession().getTransaction().commit();
} catch (RuntimeException e) {
    factory.getCurrentSession().getTransaction().rollback();
    throw e; // or display error message
}

また、このドキュメントを確認すると役立つ場合があります。

于 2013-10-29T17:04:31.697 に答える