4

我有一个我正在尝试解决的问题。我需要暂时锁定表上的读取。

这是场景。

我必须阅读一个表格来确定以基数开头的最大销售订单。然后我必须在小数点后添加数字。因此,如果我们有订单 123.1 和 123.2,我需要确定下一个需要创建的订单是 123.3。然后我调用 API 来创建这个订单号。

问题是当两个用户同时想要将新的销售订单添加到基本 123 订单号时。一位用户的逻辑确定该号码为 123.3,并调用 API 创建订单;一旦创建我提交记录。但是当 API 调用开始时,第二个用户的逻辑正在尝试确定下一个号码,并且根据时间,它还可以选择 123.3 作为下一个可用号码。

然后,一旦第二个用户的逻辑调用 API,号码就会重复并出错。

我想让第一个逻辑锁定表以防止读取,同时它确定订单号并创建它。然后我可以释放锁,第二个用户可以继续。

我读过的所有内容似乎都在说我无法阻止对表格的读取。

4

2 回答 2

5

您可以使用两个表:ORDERORDER_LINE.

生成数字的过程将执行 a SELECT * FROM order WHERE order_id = 123 FOR UPDATE,然后从 中的行确定适当的数字ORDER_LINE

如果两个会话同时使用相同的 API 调用 API order_id,则其中一个会话将等到第一个会话提交/回滚。一旦第一个会话提交,第二个会话将获得主表上的锁,然后是下一个数字。

会话可以在不同的情况下同时调用order_id而无需等待。

如果您不想等待并发更新,请使用FOR UPDATE NOWAIT并返回订单已被其他用户锁定的消息。

于 2013-05-29T15:34:35.743 回答
4

锁定读取不是答案——您不能直接在 Oracle 中锁定读取,而且锁定过于全面。

您需要做的是序列化每个基本订单号的密钥生成过程。

最有效的方法是使用 DBMS_Lock,并通过请求“ORDER123NEWKEY”(例如)的独占锁来启动新的密钥生成过程。当插入新行并提交更改时,您将释放锁定。

于 2013-05-29T15:22:15.700 回答