2010-05-27 60 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