2013-08-13 1 views
2

잠시 동안 검색했지만 수행하려는 작업에 대한 예제를 찾지 못했습니다.다중 스레드 응용 프로그램에 대한 최대 절전 모드 getOrCreate 패턴


우리는 많이 사용 아래에있을 것입니다 API를 가지고있다. 작업 중 하나는 새로운 Client 도메인 개체를 만드는 것입니다. 각 Client의 이름은 고유합니다.

다음 코드에서 우리는 클라이언트를 이름으로 읽습니다. 존재하지 않으면, 우리는 그것을 창조하려고합니다. 2 개 스레드가 잠재적으로 같은 시간에 같은 클라이언트를 만들려고 할 수있다, 우리는 다음 ConstraintException와는 다른 스레드가 우리 앞에에 도착 넣다 다른 검색을 잡을 :

@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false, isolation = Isolation.READ_COMMITTED) 
public Client getOrCreate(String name) { 
    DetachedCriteria query = DetachedCriteria.forClass(Client.class).add(Restrictions.eq("name", name)); 

    Client client = entityDao.findSingle(Client.class, query); 

    if (client == null) { 
     client = new Client(); 
     client.setName(name); 
     try { 
      entityDao.save(client); 
     } catch (ConstraintViolationException e) { 
      client = entityService.findSingle(Client.class, query); 
     } 
    } 
    return client; 
} 

최대 절전 모드에 있기 때문에,이 코드 불평

org.hibernate.AssertionFailure: null id in com.mydomain.Client entry (don't flush the Session after an exception occurs) 

나 최대 절전 모드에서 할 노력하고있어 달성하기위한 표준 패턴이나 방법이 있나요 : 예외 우리는 예외에 포함 된 세션을 사용하려는?

답변

2

당신은 새로운 트랜잭션 (세션)을 사용하기 위해, 캐치를 이동하고 트랜잭션에서 다시 시도해야합니다

Client client; 
try { 
    client = clientService.getOrCreate(name); 
} 
catch (ConstraintViolationException e) { 
    client = clientService.getOrCreate(name); 
} 

@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false, isolation = Isolation.READ_COMMITTED) 
public Client getOrCreate(String name) { 
    DetachedCriteria query = 
     DetachedCriteria.forClass(Client.class).add(Restrictions.eq("name", name)); 

    Client client = entityDao.findSingle(Client.class, query); 

    if (client == null) { 
     client = new Client(); 
     client.setName(name); 
     entityDao.save(client); 
    } 
    return client; 
} 
관련 문제