如何使用oracle数据库处理jdbc中的死锁/挂断?

时间:2011-09-18 23:12:54

标签: java oracle jdbc deadlock

我编写了一个使用jdbc将记录插入表A的应用程序。现在我发现每当我从其他客户端向表中插入记录并且没有提交时。我的应用程序将挂起插入sql,直到我从其他客户端提交更改 我该如何避免这个问题?我不希望我的应用程序等到其他客户端提交更改。

2 个答案:

答案 0 :(得分:3)

INSERT通常不应该彼此等待。

当您尝试从两个并发事务中插入相同(主要)密钥时,一个例外是:

  • 第一个到达INSERT的将继续正常,
  • 但是第二个将在其INSERT停止,直到第一个提交(导致第二个中的密钥违规)或回滚(允许第二个正常继续)。

UPDATE和INSERT之间的交互甚至DELETE和INSERT也可能导致类似的停顿。

你总是可以通过SQL Developer等通用工具人为地触发这种行为,我不会太担心。

但是,如果您有一堆客户端应用程序长时间相互拖延,您应该尝试缩短事务的长度或重新设计数据库(例如,使用SEQUENCE保证自动分配唯一的PK )和/或客户逻辑使这些“冲突”最小化。

答案 1 :(得分:1)

Branko提到的是其中一个原因。这是我在使用Transactional查询调试应用程序时所犯的错误,我只是在使用oracle.jdbc.OracleDriver瘦客户端执行插入查询而不使用提交/回滚时退出调试。

然而,这里没有提到的,如果您碰巧运行SQL客户端浏览器,即SQL Developer检查您的表或同时验证您的插入语句,它们也是导致冻结的罪魁祸首。在调试模式下,当逐步执行代码(即statement.executeUpdate();)时,您会注意到您的代码似乎无限期地等待服务器响应......很长时间......没有给出异常。如果再次执行先前未提交的查询,则会发生这种情况。你会发现你的SQL浏览器连接也受到影响。

这还取决于您构建查询的方式

i.e: 
insert into TB1(ID, Name) values (1, 'User1') x 2 times w/o commit --> freeze on 2nd time 
insert into TB1(ID, Name) values (SEQ.nextval, 'User1') x 2 times w/o commit --> OK, won freeze on 2nd time 
*where ID = auto number* 

解决方案:

停止管理连接的调试/运行时服务器。关闭/断开所有SQL浏览器。最简单的方法是关闭SQL浏览器,如果你不确定,请重启eclipse / netbean IDE。

有时您可能需要DBA权限来释放(回滚/提交)那些未提交的事务积压。 RDBMS服务器在同一个col bfr移动到您的下一个查询时等待对这些查询的操作。

如果不需要,请通过设置Connection对象来使用事务查询:

<connection>.setAutoCommmit(true)