2012-06-21 2 views
0

webservice + 최대 절전 모드에서 교착 상태가 발생했습니다 ... 이유가 없습니다.최대 절전 모드 교착 상태

내가 가지고있는 웹 서비스 코드 (함수의 핵심 코드)

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 : 잠금을 얻으려고 시도 할 때 교착 상태가 발견되었습니다. org.hibernate.collection.AbstractPersistentCollection.setCurrentSession (AbstractPersistentCollection 두 개의 열린 세션 과 모음을 연결하는 불법 시도 : sun.reflect.NativeConstructorAccessorImpl.newInstance0 (기본 방법)

org.hibernate.HibernateException에서 거래 를 다시 시작하십시오. 자바 : 435)

ERROR com.icdb.TimelineProcessor - processTimeline - 에러하면 타임 라인을 처리 중에 :: 는 org.hibernate.exception.LockAcquisitionException : 인한 [com.icdb.data.Activitylog]

을 : 삽입 없었다 작성자 : com.mysql.jdbc.exceptions.jd bc4.MySQLTransactionRollbackException : 잠금을 얻으려고 시도 할 때 교착 상태가 발견되었습니다. processTimeline - - sun.reflect.NativeConstructorAccessorImpl.newInstance0 (기본 방법)

ERROR com.icdb.TimelineProcessor에서 거래 를 다시 시작하십시오 타임 라인을 처리하는 동안 :: org.hibernate.HibernateException을 오류 : 두 사람과 함께 컬렉션을 연결하는 불법 시도

정말 도움이 appriciate 것이다 열려있는 세션

... 감사가 좋아하지 않는 것을

답변

2

잘 Hibernate는 당신을 말하고 많은 :

Illegal attempt to associate a collection with two open sessions 

두 개의 세션을 열고 각각에 트랜잭션이 있으며 두 번째 세션에서 새 타임 라인을 저장할 때 activityLog가 있고 activityLog에는 첫 번째 세션에서 생성 된 사용자와 레시피가 있습니다. 바로 그 곳에서 절전 모드가 시작됩니다.

나는 당신이 성취하려는 것을 확신하지 못합니다. 별도의 두 세션이 필요한 이유가 있습니까? 타임 라인은 의미 적으로 제조법/사용자 엔티티와 관련된 것이거나 타임 스탬프 컬렉션과 더 비슷합니까? 전자의 경우 사용자, 제조법 및 타임 라인을 하나의 동일한 콜렉션에 저장하려고합니다. 그렇지 않으면 하나의 트랜잭션이 성공하고 다른 트랜잭션이 실패하면 손상된 데이터로 끝납니다. 후자의 경우 Timestamp 서비스는 엔터티 대신 인수로 값 개체를 가져와야합니다. 아마도 응용 프로그램의 다른 부분에서 값 개체에 액세스하려고 할 것이기 때문입니다.

+0

나는 본다. 타임 라인은 모든 사용자 활동을 기록하는 데 사용됩니다 (페이 스북과 같은 타임 라인에 표시 ...). 서비스 호출이 빠르기 때문에 스레드에서 사용합니다.이 작업은 BG에서 수행 할 수 있습니다. 그래서 내가 당신의 대답을 이해함에 따라 - 나는 이드들을 ​​패스해야합니다. 사용자 만들기 u = 새 사용자(); u.setId (i_userId), 그럼 제대로 이해하면 문제를 해결해야합니까? – user1136875

+2

그 방법은, 특히 당신이 SessionFactory와 TimelineSessionFactory를 가지고 있기 때문에, 언젠가 타임 라인이 완전히 다른 데이터베이스 서버에 저장되고 결국 엔티티 대신에 메시지를 전달해야한다는 힌트입니다. .이를 구현하는 방법은 또 하나의 질문입니다. TimelineService가 int 및 String과 같은 원시 데이터 만 가져올 수 있도록 만든 다음, App 클래스의 일부를 알지 않고도 응용 프로그램의 일부 다른 부분에 액세스 할 수 있습니다. 또는 DTO 복사본을 사용할 수도 있고 직접 만들 수도 있고 도저 같은 도구를 사용할 수도 있습니다. 두 가지 방법 모두 장점이 있습니다. – wallenborn

+0

고마워요. 큰 도움이되었습니다. 귀하의 요점이 – user1136875