我有一个问题,我想在这种情况下使用数据库isolationtype == Serializable,但在阅读了一堆文章后,我仍然不相信这是我下面问题的解决方案。
设置:
Weblogic cluster > 2 servers
Simple Java JDBC
Servlets, EJB Session beans 2.0
我有一个表LAN
,我们根据客户端给出的输入选择匹配值。
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_Assignment
LAN_Assignment
lan_id | lan_assg_id | some other columns
-------------------------------------------
运行select语句时,我从LAN表中获取匹配的行并将其分配给lan_assignment表。
现在如果有5个来自客户端的请求(可能是群集中的任何服务器),它们都会选择第一个可用的LAN并将其保存到另一个表中。
如何确保来自客户端的第二个请求未选择第一个接收LAN的请求?
PS:select语句和业务逻辑并不像这里解释的那样直截了当。有很多条件可以选择LAN并将其保存到Lan_assignment等。
谢谢
答案 0 :(得分:2)
您可以使用SKIP LOCKED作为目的。当会话1锁定行时,会话2可以跳过它并处理下一行。我相信它也存在于10g中,但从未记录过。
答案 1 :(得分:1)
Serializable隔离不是您问题的解决方案(但请留在那里!)
您有几种方法可以处理这5个并发请求(根据您的方案)。一种是失败4次交易,只有1次会成功。您可以使用唯一约束或使用乐观锁定来执行此操作,并重试因此而失败的操作(但请记住在几次重试后失败)。
或者,你可以使用行锁,如果音量不大,这种方法应该可以正常工作。
答案 2 :(得分: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