2013-02-23 93 views
0

我正在嘗試開發一個演示來強化我對REPEATABLE_READ隔離級別的理解。我嘗試過使用hibernate和jdbc進行演示。 JDBC按預期工作,但休眠不。事務隔離級別REPEATABLE_READ使用休眠和jdbc

我的期望是,如果我在一個會話中讀取數據庫行,並嘗試從另一個會話寫入同一行,它應該阻塞,直到第一個會話結束。當我在線程0和睡眠中獲得一個對象(行),並且在線程1中我們嘗試更新同一個對象(行)時,線程1應該等到線程0提交。

class HibernateExample7_IsolationRR_Read_Write_Thread implements Runnable { 

    private static final Logger logger = LoggerFactory.getLogger(HibernateExample7_IsolationRR_Read_Write_Thread.class); 

    SessionFactory sessionFactory; 
    int sleep; 
    int newnumberplate; 
    public HibernateExample7_IsolationRR_Read_Write_Thread(SessionFactory sessionFactory, int sleep, int newnumberplate) { 
     this.sessionFactory = sessionFactory; 
     this.sleep = sleep; 
     this.newnumberplate = newnumberplate; 
    } 

    public void run() { 
     Session session = sessionFactory.openSession(); 
     Transaction tx = session.beginTransaction(); 
     logger.info("TRYING TO GET VEHICLE 1"); 
     Vehicle vid1 = (Vehicle) session.get(Vehicle.class, Integer.valueOf(1)); 
     logger.info("GOT VEHICLE 1"); 
     vid1.setNumberplate(this.newnumberplate); 
     logger.info("SET NUMBERPLATE FOR 1"); 
     try { 
      Thread.sleep(sleep); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     tx.commit(); 
     session.close(); 
     logger.info("COMMITED"); 
    } 
} 

hibernate.connection.url是JDBC:德比:隔離;創建=真和hibernate.connection.isolation是。我創建了HibernateExample7_IsolationRR_Thread的兩個對象,並創建了Thread 0獲取車輛並長時間睡眠的場景。同時線程1試圖獲取和更新車輛。它甚至在線程0提交之前成功提交。

由於REPEATABLE_READ隔離級別,T1不應等待提交。如果不是,那麼它是READ_COMMITED隔離級別而不是REPEATABLE_READ隔離級別。

+0

您正在使用什麼版本,如果HSQLDB? – sharakan 2013-02-23 03:56:42

+0

hsqldb 2.2.8版 – 2013-02-23 04:41:51

回答

1

你的期望是錯的。可重複讀取並不意味着一個事務應該阻塞,而另一個事務讀取同一行。這意味着即使另一個事務在第一次讀取和第二次讀取之間提交了對該行的更改,在同一事務中讀取同一行兩次也應該返回相同的數據。

由於第二次讀取將從第一級緩存中返回數據而根本不需要訪問數據庫,因此可以免費使用Hibernate(或多或少)。

http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Non-repeatable_reads

而且,你讓你的測試與不支持此隔離級別數據庫:

http://www.hsqldb.org/doc/2.0/guide/dbproperties-chapt.html#N15385

+0

Nitpicky:他會達到二級緩存,對吧?每個線程都有自己的會話。 – sharakan 2013-02-23 13:50:00

+0

@sharakan:沒有。一個單線程,在同一事務中獲得兩次相同的實體,將首次觸及數據庫,第二次觸及第一級緩存。因此,它將具有可重複的讀取,因爲第一級緩存將返回第一次返回的相同數據(當然,除非在讀取之間對實體進行了一些更改)。 – 2013-02-23 13:52:49

+0

同意,但他有兩個獨立的線程,每個線程調用.openSession,因此有單獨的第一級緩存。 – sharakan 2013-02-23 15:07:46