【问题标题】:Dead lock is happening same data base record updating in multiple connection sessions concurrently死锁在多个连接会话中同时发生相同的数据库记录更新
【发布时间】:2010-10-01 07:11:12
【问题描述】:

我们已经实现了基于客户端服务器套接字的应用程序来处理多个购物车请求。每天我们都会收到数以千计的购物车请求。

为此,我们实现了多线程架构来同时处理请求。我们将 Oracle 连接池用于数据库操作,并为连接池大小设置了最佳值。根据我们的业务流程,我们有一个主数据库表,我们需要通过多个线程同时使用多个连接会话更新同一组行。现在遇到了一些死锁问题,因为多个线程将尝试同时使用多个连接会话更新同一行上的数据,而且我们还有其他一些表上的主键违规。有时,通过同时在多个连接会话中插入相同的数据,数据库也会被锁定。

请建议我立即处理上述问题的好方法。

【问题讨论】:

  • 如果您能向我们展示一些代码,那将有所帮助...一般来说,如果您必须更新相同的数据,这些操作将被序列化...

标签: oracle deadlock


【解决方案1】:

编写不会遇到死锁的多线程代码有几种不同的通用解决方案。最简单的方法是确保您始终以相同的顺序锁定资源。

当一个会话持有 A 的锁并希望锁定 B 而另一个会话持有 B 的锁并希望锁定 A 时,就会发生死锁。如果您确保您的代码始终在 B 之前锁定 A(或 B 在A),可以保证不会出现死锁。

至于您对主键违规的评论,您是否使用 Oracle 序列以外的东西来生成主键?如果是这样,那几乎肯定是问题所在。 Oracle 序列被明确设计为在您有多个会话同时进行插入的情况下提供唯一的主键。

【讨论】:

  • 感谢 Cave 的及时回复。我们为每个线程的特定代码段实现了一些等待和通知机制。通过这种方法,死锁不会发生。但这种方法的缺点是,如果任何线程花费大量时间会影响其他线程,因为该过程将是串行方式。如果我们把所有的数据库操作写在存储过程中,当所有线程都访问这个存储过程时,是不是给每个线程加了锁?
  • 我们在子表中发现了一些主要违规行为,而不是在父表中。这个问题我们将通过再次运行进程来处理。主要问题是当每个线程尝试同时在每个不同的连接会话中插入或更新数据子表时,数据库被锁定。甚至有时系统也被绞死了。我们正在批量添加所有插入或更新 sql 语句。实际上,在这种情况下,我们应该得到死锁,但数据库没有抛出任何异常。对于这个过程我们还没有实现上面的等待和通知机制。
猜你喜欢
  • 2021-11-27
  • 1970-01-01
  • 2020-01-26
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 2012-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多