2016-08-10 1 views
1
자바 최대 절전 모드에서

, 우리는 DB와 함께 뭔가를 할 필요가있을 때 우리가 필요 1. 세션 2. 거래를 시작 3. 마침 거래 4. 닫기 세션세션 및 트랜잭션

  • 예를 들어

    나는 학생 목록을 얻으려면 :

    public static List<Student> getStudentList() 
    { 
        List<Student> l = null; 
        Session session = HibernateUtil.getSessionFactory().openSession(); 
        try { 
         String hql = "from Student"; 
         Query query = session.createQuery(hql); 
         l = query.list(); 
        } catch (HibernateException ex) { 
         //Log the exception 
         System.err.println(ex); 
        } finally { 
         session.close(); 
        } 
        return l; 
    } 
    
  • 학생 삽입을

    public static boolean addStudent(Student s) 
    { 
    Session session = HibernateUtil.getSessionFactory().openSession(); 
    
    if (... /* check if student is already exists*/) 
    { 
        return false; 
    } 
    Transaction transaction = null; 
    
    try { 
        transaction = session.beginTransaction(); 
        session.save(s); 
        transaction.commit(); 
    } catch (HibernateException ex) { 
        //Log the exception 
        transaction.rollback(); 
        System.err.println(ex); 
        } finally { 
         session.close(); 
    } 
    return true; 
    } 
    

getStudentList()에 트랜잭션이없는 이유는 무엇입니까? 미리 감사하십시오

답변

1

이 최대 절전 모드 article은 트랜잭션 내에서 명시 적으로 실행되지 않는 SELECT 작업의 동작을 설명합니다.

다음 예제는 기사에 나와 있지만 쿼리 예제에도 해당됩니다.

세션 세션 = sessionFactory.openSession();
session.get (Item.class, 123l);
session.close();

  1. 새 세션이 열립니다. 이 시점에서 데이터베이스 연결을 얻지 못합니다.
  2. get()을 호출하면 SQL SELECT가 트리거됩니다. 이제 세션은 연결 풀에서 JDBC 연결을 가져옵니다. Hibernate는 기본적으로 setAutoCommit (false)로이 커넥션의 자동 커밋 모드를 즉시 해제한다. 이것은 JDBC 트랜잭션을 효과적으로 시작합니다!
  3. SELECT는이 JDBC 트랜잭션 내에서 실행됩니다. Session은 닫히고, 연결은 풀로 반환되고 Hibernate에 의해 해제된다 - Hibernate는 JDBC Connection에서 close()를 호출한다. 커밋되지 않은 트랜잭션은 어떻게됩니까?

이 질문에 대한 대답은 "달라집니다!"JDBC 사양은 연결에서 close()가 호출 될 때 보류중인 트랜잭션에 대해 아무 말도하지 않습니다. 벤더가 스펙을 구현하는 방법에 따라 달라집니다. 예를 들어 Oracle JDBC 드라이버의 경우 close()를 호출하면 트랜잭션이 커밋됩니다. JDBC Connection 객체가 닫히고 리소스가 풀로 반환되면 대부분의 다른 JDBC 공급 업체는 동일한 경로를 사용하여 대기중인 트랜잭션을 롤백합니다. 이 문제는 SELECT [...]에 대해서는 문제가되지 않습니다.

가능한 문제를 유발할 수 있도록 위의 예를 확장하십시오. Item에 대한 새로운 가격은 지속 여부를 경우

Session session = sessionFactory.openSession(); 
Item item = session.get(Item.class, 123l); 
item.setPrice(10); 
session.close(); 

는 이제 JDBC 드라이버에 따라 달라집니다.

따라서 데이터베이스 변경 사항이없는 한 JDBC 드라이버가 트랜잭션을 롤백 할 때에도 SELECT 순수 작업으로 트랜잭션을 시작하고 커밋 할 수 있습니다.

하지만 어쨌든 오해와 문제를 피하기 위해 모든 작업에서 트랜잭션을 사용하는 것이 좋습니다.

관련 문제