2010-05-27 58 views
3
水平

我有一個做了批量插入到一個MySQL數據庫中的原生查詢:JPA和MySQL的事務隔離

String sql = "insert into t1 (a, b) select x, y from t2 where x = 'foo'"; 
    EntityTransaction tx = entityManager.getTransaction(); 
    try { 
     tx.begin(); 
     int rowCount = entityManager.createNativeQuery(sql).executeUpdate(); 
     tx.commit(); 
     return rowCount; 
    } 
    catch(Exception ex) { 
     tx.rollback(); 
     log.error(...); 
    } 

這個查詢將導致死鎖:當它從t2insert .. select讀取,另一個進程試圖插入排成t2

我不關心t2在執行insert .. select時讀取的一致性,並且想要將事務隔離級別設置爲READ_UNCOMMITTED

如何在JPA中設置它?


更新

所以我結束了創建針對這種情況,因爲在我看來,最簡單的選擇一個普通的SQL連接。感謝大家!

+0

我不明白它是如何導致死鎖?如果tx1執行: insert into t1(a,b)從t2中選擇x,y其中x ='foo' 雖然這發生在第二個tx插入到「t2」表中,但tx1有一個等待,直到tx2結束後,tx2結束tx1繼續它的工作。 Dedalock意味着tx2在插入t2的同時也會從t1讀取數據?這是你的情況嗎?插入t1(a,b)從t2中選擇x,y其中x ='foo' tx2:插入到t2(a,b)中選擇x,y從t1其中x ='foo' – Pavel 2014-06-04 21:04:56

回答

4

您需要在連接級別設置它,得到了EntityManager了會議,並做到這一點:

org.hibernate.Session session = (Session)entityManager.getDelegate(); 
Connection connection = session.connection(); 
connection.setTransactionIsolation(Connection.READ_UNCOMMITTED); 
+0

我正在使用實體管理器,而不是會話。 – armandino 2010-05-27 19:24:32

+0

這就是爲什麼我說「從電話會議」;)我編輯代碼 – Guillaume 2010-05-27 19:30:42

+4

,以及如果它不休眠? – Bozho 2010-05-28 05:00:04

3

在JPA你不知道。 JDO是唯一支持設置txn隔離的標準。很顯然,特定的實現方法可以允許它,但是隨後你變得不可移植

0

由於您正在使用BMT,您可以使用數據源執行以下操作以獲取連接。 並設置iso。水平。

DataSource source = (javax.sql.DataSource) jndiCntxt.lookup("java:comp/env/jdbc/myds"); 
Connection con = source.getConnection(); 
con.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED); 
+1

如果他不使用DataSource,而是指定了connectionURL? – DataNucleus 2012-11-09 07:48:21