【问题标题】:How to handle row lock contention at application level如何在应用程序级别处理行锁争用
【发布时间】:2018-02-11 13:01:22
【问题描述】:

我有 2 个应用程序(Spring - Hibernate with Boot)使用相同的 oracle 数据库(11g)。这两个应用程序始终命中一个特定的表,并且该表上有大量的命中。我们可以在数据库日志中看到行锁争用异常,并且每次我们得到这些异常或者当它产生类似死锁的情况时都必须重新启动应用程序。

我们正在为这些应用程序使用 JPA 实体管理器。 在这个问题上需要帮助

【问题讨论】:

  • 当一个表不断插入和更新时会出现此问题。
  • 2 个应用程序中的一个实现了 5 个 spring 调度程序,它们也命中同一张表。很抱歉在 cmets 部分添加信息。

标签: java spring jpa row contention


【解决方案1】:

根据此链接: http://www.dba-oracle.com/t_enq_tx_row_lock_contention.htm

发生此错误是因为一个事务正在等待另一个事务提交或回滚......从数据库 POV 来看,这种行为是正确的,如果您考虑数据一致性......但如果可用性/履行是一个问题为你...你可能需要做一些工作,包括:

1 为每个应用程序创建单独的表,然后用离线数据更新主表(但你会牺牲数据一致性)

2 创建一个单独的线程来记录和重试不成功的事务

3 承担可用性问题(延迟)如果一致性是一个大问题

还有一些一般的提示要考虑:

1 使事务最小化...考虑事务中包含的每个进程。如果它是强制性的或可以在外面删除

2 调整事务分界...你可能会发现事务无故打开很长时间,但编码错误

3 不要在事务中进行读操作

4 尽可能避免扩展持久性上下文(无状态)

5 你可能会选择使用非 jta 事务数据源来报告和读取查询

6 检查您正在使用的锁类型,并尽量避免 - 根据您的情况 - 除了 OPTIMISTIC 之外的任何东西

但最后你同意我的观点,我们不应该责怪数据库阻止两个事务修改同一行。

【讨论】:

  • 感谢您的回答..!!我创建了一个单独的服务,它消耗来自这些应用程序的休息调用,并且该服务插入/更新表。还添加了 PESSIMISTIC_WRITE 锁以避免死锁。请让我知道您对此的看法。
  • 如果我理解正确,那么不是让 2 个应用程序同时写入同一个数据库,而是创建另一个 WS 消耗两者并写入数据库,因此不再有同步问题......如果是这种情况,我认为不需要锁(除非出于其他我不知道的原因)......据我所知,乐观锁并不能避免死锁,相反,你正在增加受保护区域的表面积使其更容易发生死锁,特别是如果您使用扩展锁定模式(锁定实体及其相关)
  • 我们仍然遇到同样的问题。我认为交易是长期开放的。有超时日志表明这一点。单个事务包含对不同表的插入和更新。乐观锁不能防止死锁。请提供任何可以提供进一步帮助的解决方案。
  • cab你请确认我在之前评论中提到的案例描述
  • 对不起,我的意思是:pessimistic 锁不能避免死锁
猜你喜欢
  • 2011-12-27
  • 1970-01-01
  • 2010-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多