3

我有一个问题,我正在考虑在这种情况下使用 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:选择语句和业务逻辑并不像这里解释的那么简单。选择LAN并保存到Lan_assignment等有很多条件,

谢谢你

4

3 回答 3

2

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

于 2015-03-04T22:05:07.030 回答
1

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

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

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

于 2015-03-04T22:02:19.603 回答
1

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
于 2015-03-05T15:22:06.220 回答