数据库 select 语句的并发问题

Concurrency issue on a database select statement

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

设置:

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

我有一个 table 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 中挑选一个匹配的行并保存另一个 table LAN_Assignment

LAN_Assignment

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

当 运行 一个 select 语句时,我从 LAN table 得到匹配的行并将其分配给 lan_assignment table。

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

如何确保选择 LAN 的第一个请求没有被客户端的第二个请求select编辑?

PS:select 语句和业务逻辑并不像这里解释的那样直接。有很多条件选择局域网,保存到Lan_assignment等,

谢谢

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

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

或者,你可以使用行锁,如果体积不是很大,这种方法应该可以。

当会话 1 锁定该行时,您可以将 SKIP LOCKED 用于 purpose.With,会话 2 可以跳过它并处理下一个。我相信它也存在于 10g 中,但从未记录在案。

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

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

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

select .. where .. for update

Option 2:(Nowait) 如果行被其他一些事务锁定,这将不会等待。它会 return oracle 错误。我可能会捕获异常等待 10 秒,然后再尝试 4-5 次尝试,然后再向用户显示错误。

select .. where... for update nowait

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

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