2017-09-30 1 views
0

우리는 DB 트랜잭션에서 비정상적인 동작을보고 있습니다. 이들은 원자 적으로 작동하지 않습니다. MySQL 5.6.25 Innodb, Eclipselink 2.5.2를 JPA 공급자, HikariCP 2.6.2를 연결 풀로 사용합니다.비 원자 동작 Eclipselink- DB 트랜잭션 반품

이 문제는 Eclipselink가 entityManager.flush 호출 중에 풀에서 연결을 가져 오지 못할 때 나타납니다. 언젠가는 특정 테이블에 대한 항목이 최선의 노력을 기울여 이루어 졌기 때문에이 예외를 삼키는 것입니다. 감사 모드라고 할 수 있습니다. 그러나 이로 인해 트랜잭션의 일부만이 커밋되었지만 5 ~ 3 개 항목 만 유지되었습니다.

여기에 연결 인수는 다시 나중에 플러시의 어느 시점에서 실패 할 때 이벤트

tx.begin(); 
    em.persist(entity1); 
    try{ 
     em.persist(entity2); 
     em.flush(); ---> this is where connection acquisition fails. 
    } catch(Throwable tx){ 
    //do nothing, except log. 
    } 
    em.persist(entity3); 
    em.flush(); 
    em.persist(entity4); 
    em.flush(); 
    em.persist(entity5); 
    em.flush(); 

    em.persist(entity6); 
    tx.commit(); 

우리는 entity3, entity4, entity5까지 최선을 다하고 거래를보고있다의 흐름입니다입니다,해야합니다.

정확히 어떻게 이런 일이 발생했는지 나타낼 수 있습니까?

+0

다른 MySQL 백엔드는 다른 동작을하고 일부는 ACID 트랜잭션이 없습니다. 당신이 사용하는 것 (innodb, myisam etc.) –

+0

Innodb. 이 선행을 언급하겠습니다. – user20507

+0

flush에서 예외를 catch 한 다음 트랜잭션을 계속할 수 없습니다. – Chris

답변

0

주된 문제는 연결을 사용할 수 없다는 것입니다. 이런 종류의 예외 인 경우 이어야 트랜잭션을 롤백 할 수 있습니다. 처리되지 않은 트랜잭션을 잡으면 트랜잭션의 동작이 변경됩니다. 첫 번째 em.flush()도 예외는 잃지 않으려는 첫 번째 em.persist(entity1)을 삭제합니다.

따라서 try 앞에 em.flush()을 추가하여 엔티티 1의 지속성이 보장되거나 예외가 발생하여 전체 트랜잭션이 롤백되도록해야합니다.

비록 이런 종류의 솔루션을 권장하지 않습니다.

entity2의 지속성이 선택 사항 인 경우 일반적으로 추가 트랜잭션에서이를 수행 할 수 있습니다. 즉, 시스템은 짧은 시간 동안 추가 db 연결을 필요로합니다.

추가 트랜잭션을 만드는 방법은 무엇입니까? Ejb에서는 주석 처리 된 REQUIRES_NEW 메소드를 사용합니다. 어떤 종류의 TransactionManagement를 여기에서 사용하고 있는지 확실하지 않지만, 일종의 별도 트랜잭션 (중첩 된 트랜잭션으로 혼동되지 않도록 !!)을 생성 할 수 있어야합니다.

관련 문제