0

Webサービス+休止状態でデッドロックが発生しています...理由がわかりません。

次のWebサービスコード(関数のコアコード)があります

public String createImageRecipe(...)
{
    Session session = ICDBHibernateUtil.getSessionFactory().getCurrentSession();
    try 
    {
        session.beginTransaction();

        User user = (User) session.load(User.class, userid);

        // Create the recipe
        Recipe recipe = new Recipe();
        ...
        ...
        ...

        session.save(recipe);
        session.save(user);

        ...
        ...
        ...

        session.update( recipe );

        // Add new entry to activity log
        Activitylog activityLog = new Activitylog(  user, 
                                                    (byte) ActivityTypeEnum.USER_SHARED_RECIPE.ordinal(), 
                                                    new Date() );
        activityLog.setRecipe(recipe);
        TimelineProcessor.saveTimeline( activityLog, null, true );

        session.getTransaction().commit();

        endMeasurement();

        return recipe.getRecipeid() + "," + recipe.getImageRecipeUrl();
    } 
    catch (RuntimeException e) 
    {
        ICDBHibernateUtil.getSessionFactory().getCurrentSession().getTransaction().rollback();
        throw e;
    }
}

タイムライン スレッド (TimelineProcessor) は、(メッセージを取得した後) 次の処理を実行します。

    Session session = ICDBHibernateUtil.getTimelineSessionFactory().openSession();
    try {
        session.getTransaction().begin();

        ...
        ...
        ...

        TimelineId tlId = new TimelineId();
        tlId.setUserId(userId);

        User u = new User();
        u.setUserid(userId);

        Timeline tl = new Timeline(tlId, timelineData.getActivitylog(), u);
        session.save(tl);

        session.getTransaction().commit();
        session.close();
    } catch (Exception e) {
        logger.error("Error while processing timeline :: ", e);
        session.getTransaction().rollback();
    }
}

ログからの例外: 原因: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: ロックを取得しようとしたときにデッドロックが見つかりました。sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) でトランザクションを再開してみてください

org.hibernate.HibernateException: org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:435) でコレクションを 2 つの開いているセッションに関連付ける不正な試み

エラー com.icdb.TimelineProcessor - processTimeline - タイムラインの処理中にエラーが発生しました:: org.hibernate.exception.LockAcquisitionException: 挿入できませんでした: [com.icdb.data.Activitylog]

原因: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: ロックを取得しようとしたときにデッドロックが見つかりました。sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) でトランザクションを再開してみてください

エラー com.icdb.TimelineProcessor - processTimeline - タイムラインの処理中にエラーが発生しました :: org.hibernate.HibernateException: コレクションを 2 つの開いているセッションに関連付けようとする不正な試み

本当に感謝します...どうもありがとう

4

1 に答える 1

2

さて、Hibernate は気に入らないことを伝えています。

Illegal attempt to associate a collection with two open sessions

2 つのセッションを開いていて、それぞれにトランザクションがあり、2 番目のセッションで新しいタイムラインを保存すると、ActivityLog があり、その activityLog には最初のセッションに由来するユーザーとレシピがあります。それがHibernateの鳴き声です。

あなたが何を達成しようとしているのかわかりません。2 つの別々のセッションが必要な理由はありますか? タイムラインはレシピ/ユーザー エンティティに意味的に関連付けられているものですか、それともタイムスタンプ コレクションのようなものですか? 前者の場合、ユーザー、レシピ、およびタイムラインを 1 つの同じコレクションに格納したいと思うでしょう。そうしないと、1 つのトランザクションが成功し、もう 1 つのトランザクションが失敗した場合にデータが破損することになります。後者の場合、Timestamp サービスはエンティティではなく値オブジェクトを引数として受け取る必要があります。これは、アプリケーションのさまざまな部分からアクセスする必要があるためです。

于 2012-06-21T16:21:20.773 に答える