【问题标题】:Concurrency issue on a database select statement数据库选择语句的并发问题
【发布时间】:2015-03-04 21:52:36
【问题描述】:

我有一个问题,我正在考虑使用 databaseisolationtype == Serializable 来解决这种情况,但是在阅读了一堆文章后,我仍然不相信这是解决我下面问题的方法。

设置

Weblogic cluster > 2 servers
Simple Java JDBC
Servlets, EJB Session beans 2.0

我有一个表LAN,我们根据客户提供的输入选择匹配值。

局域网

lan_id   | name | some_values | is_available
-------------------------------------
13       |  ss  | 3234        | yes 
12       |  sssd| 3234        | yes
14       |  sssd| 3234        | yes
15       |  ssaa| 3234        | yes

现在在业务逻辑中,我需要从 LAN 中选择一个匹配的行并保存另一个表 LAN_Assignment

LAN_Assignment

lan_id   | lan_assg_id | some other columns
-------------------------------------------

运行 select 语句时,我从 LAN 表中获取匹配行并将其分配给 lan_assignment 表。

现在如果有 5 个请求来自客户端(可以是集群中的任何服务器),它们都会选择第一个可用的 LAN 并将其保存到另一个表中。

如何确保客户端的第二个请求没有选择第一个获取 LAN 的请求?

PS:select 语句和业务逻辑并不像这里解释的那么简单。选择LAN并保存到Lan_assignment等有很多条件,

谢谢

【问题讨论】:

  • 单个原子获取和锁定函数(如在存储过程中)不会保证不会发生这种情况吗?
  • 在事务中运行 SQL 语句锁定选择的行以进行更新,这样如果其他查询最终选择相同的行,则在获得锁定之前不会前进行 - 确保您的逻辑尽可能快地运行,但不会降低性能。
  • 你使用的数据库和版本是什么?
  • @AnindaBhattacharyya Oracle 10G 是数据库
  • 我需要在文档中查找并进行一些测试,这就是我没有写答案的原因。检查您的数据库文档,无论如何 IIRC SELECT ... WHERE ... FOR UPDATE 应该在所选行上获得行独占锁。在整个事务中执行此操作,以便您可以选择行,锁定它,在其他表中写入您需要的任何内容,然后通过提交释放该行(即使您没有修改它)。大致就是我的建议。

标签: java jdbc oracle10g transaction-isolation weblogic8.x


【解决方案1】:

您可以使用SKIP LOCKED 来达到您的目的。当会话 1 锁定行时,会话 2 可以跳过它并处理下一个。我相信它也存在于 10g 中,但从未记录在案。

【讨论】:

  • 一定会看看的。
【解决方案2】:

Serializable 隔离不能解决您的问题(但请留在那里!)

您有几种方法可以处理这 5 个并发请求(根据您的情况)。一种是失败 4 次交易,只有 1 次成功。您可以使用唯一约束或使用乐观锁定来执行此操作,并重试因此而失败的操作(但请记住在重试几次后失败)。

或者,您可以使用行锁,如果卷不是很大,这种方法应该可以正常工作。

【讨论】:

  • 能否详细说明一下行锁?
【解决方案3】:

Oracle 10g 有未记录的 SKIP LOCKED 可用于更新,我将其用作解决方案(请参阅下面的选项 3)。

我是如何通过其他选项来处理这种情况的。

Option 1: 下面的选项只会锁定行直到事务完成。所有其他事务将继续等待第一个事务释放锁。这有点冒险,因为事务可能会等待很长时间并可能导致死锁。

select .. where .. for update

Option 2:(Nowait) 如果行被其他事务锁定,则不会等待。它将返回 oracle 错误。在向用户显示错误之前,我可能会捕获异常等待 10 秒并尝试另外 4-5 次尝试。

select .. where... for update nowait

选项 3:(跳过锁定)这将跳过被其他事务锁定的行,这对我来说是有目的的,因为我不想使用那些被其他事务锁定的行。

select...where ... for update skip locked

【讨论】:

    猜你喜欢
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多