使用oracle和innodb在我的场景中最小化表死锁

时间:2010-08-04 02:18:20

标签: mysql oracle innodb deadlock database-deadlocks

我有35个函数在事务中更新1到3个表。但是,它们不只是执行更新,而且还会进行查询。

  • 表1仅执行行更新操作和一些查询。
  • 表2对现有行执行查询和行级更新,有时还会删除和添加行。表2可能在行删除和/或插入和/或更新之前和之后的事务中有查询。
  • 表3根据上述表2的操作结果进行行更新。

我的第一个动作是确保表3的更新都在最后完成。

表1独立于其他2个表,可能是第一个或最后一个。 因此表2必须在表3更改之前出现。

我首先关心的是,通过表2的操作,我会进行查询,然后更新,然后查询更多查询,然后进行更多更新。我是否必须重新编写代码才能执行此操作。

我的第二个问题是表3是servlet线程必须快速的表。表3用于简单查询。但似乎行级锁将阻止这些查询。

如果必须,我可以从一个线程将上述表集维护代码放在一个集群范围的进程中。更新的速度无关紧要。只是针对表3的查询很快。而且从来没有任何僵局。

我不知道Oracle和Innodb之间的区别,所以我有疑问。 (我计划稍后升级到Oracle。)

基本上,我正在寻找有关注意事项的指示。当然,我可以在表2上强制执行完全表锁,然后在每个更新程序函数的开头强制执行表3,但随后我的Table3 servlet查询线程将受到影响。所以这似乎不是一个解决方案。

另外,我担心只是相对于表2本身,一些函数执行查询,基于查询的更新,基于更新的新查询,然后更多更新,包括流程结果直至更新到表3这看起来真的很讨厌。

建议? 安迪

可以同时更新2个表的相同行,并且我已经注意按照相同的顺序使用更新来访问表。其中一个表有2个索引,似乎需要表锁来更新索引?一些函数在重复循环中查询表1,更新表1,然后可选地查询表2,然后更新表2。此表包含我所有内容的树中的所有父子关系,因此它是所有用户的高容量更新。

1 个答案:

答案 0 :(得分:2)

首先,Oracle中的查询(我相信InnoDB)除非您使用FOR UPDATE,否则不会锁定。

其次,我不了解您的应用规模。您期望有多少并发事务?你期望他们更新相同的行吗?

可能遭遇死锁的应用程序类型是预订或售票系统(例如,人们试图在剧院预订相同的座位),尤其是在高并发情况下(新节目可用于预订)。

如果您的应用程序适合此配置文件,那么您可能希望预测死锁情况。但是,我至少会考虑简单地捕获错误,回滚然后重新尝试事务。如果您详细了解表结构,关系和更新标准,那么适当的锁定点可能会变得明显。