如何防止JPA插入锁定数据库表?

时间:2009-07-30 19:50:56

标签: java database hibernate jpa persistence

我正在使用Hibernate支持的JPA作为我的持久层。我有一个多线程进程,它聚合来自Soap调用的数据,然后在数据库中存储一行。该过程通常最终会插入大约700行,大约需要1-3个小时,而Soap调用是主要的瓶颈。

在整个过程中,我插入的表会锁定,并且不会及时返回选择语句。

这是SQL服务器错误:

  

错误消息:超出锁定请求超时时间。

如何在这个漫长的过程中避免锁定我的数据库表?

3 个答案:

答案 0 :(得分:2)

您可能需要更改隔离级别。

以下是一些信息: http://www.interview-questions-tips-forum.net/index.php/Your-Questions-on-Java/JDBC-Transaction/Transaction-Isolation-Levels

它讨论了不同的隔离级别,以及它们可以帮助防范的内容。执行此操作的一般方法是从strictist开始,然后在需要更好的响应时间时降低,同时牢记数据完整性/错误读取的要求。

修改

Spring事务级别用于在事务管理器中抽象JDBC(或其他)事务隔离级别。它们在TransactionDefinition类中定义,并且是静态成员。

TransactionDefinition.ISOLATION_DEFAULT
Default isolation

TransactionDefinition.ISOLATION_READ_UNCOMMITTED
Lowest level of isolation; allows transactions to see uncommitted modifications from other transactions

TransactionDefinition.ISOLATION_READ_COMITTED
Cannot read uncommitted data

TransactionDefinition.ISOLATION_REPEATABLE_READ
Ensures repeatable reads

TransactionDefinition.ISOLATION_SERIALIZABLE
Most reliable; all transactions are executed atomically, and are treated as though they occurred serially.

还有事务传播级别。您可能正在使用事务进行纯读取,这可能是过度的 - 读取不需要事务,写入应该始终围绕它们进行事务处理。 TransactionDefinition中的传播级别也是明确的。这些通常在弹簧布线文件中用于定义特定调用的序列化和传播。如果您有一个接线示例,我可能会提供更多提示/信息。

答案 1 :(得分:1)

您是否使用相同的交易插入所有700行?

您的交易边界在哪里?如果你可以降低你的交易边界,即只交易实际的插入操作,那么锁定是完整的。

如果你需要将整个过程变为原子过程,那么将它写入临时表然后进行批量插入(快速)以将其插入主表中可能是一个想法。

答案 2 :(得分:0)

您是否尝试在一次JPA交易中提出700个肥皂请求?不要那样做。 : - )