2010-11-01 107 views
1

我读到Oracle维护行版本来处理并发。我想在非常大的实时数据库上运行更新查询,但此更新作业必须更改该行的最新版本。有没有办法通过SQL更新最新版本的行?

这可能通过PL/SQL或简单的SQL?

编辑下面**

让我清楚的情况下,我们面临着一个非常大的数据库在现实生活中的问题。我们的客户是一家知名的手机服务提供商。

我们的数据库有一个表格,用于管理客户手机帐户上剩余的当前余额记录。在表格的其他列中,一列存储完成的再充值量,另一列存储剩余的当前有效余额。

我们有两个独立的PL/SQL脚本。客户为手机充值并更新余额时,会自动触发一个脚本。

第二个脚本是关于从客户帐户中扣除某些费用。这是一项批量工作,因为它适用于所有客户。该脚本计划在一天的特定时间间隔内运行。当此脚本运行时,它会在内存中加载50,000条记录,更新某些列并执行批量更新回到表格。

问题发生的事情是这样的:

一位顾客,他的ID是101,联系他在当地商店买东西,他的手机充电。他支付金额。但直到他的手机即将充电时,第二个脚本的预定时间才开始了第二个脚本。第二个脚本在内存中加载了50,000个客户的记录。在这个内存记录中,也是这个客户的记录之一。

直到第二个脚本的批量更新完成时,第一个脚本成功为客户的帐户充值。

现在发生了什么是实际的表,列:“CurrentAccountBalance”被更新为150,但其第二脚本工作过客户的旧的平衡,即在内存中的记录,100

第二个脚本必须从列中扣除10:“CurrentAccountBalance”。根据实际工作,当客户的“CurrentAccountBalance”应为140时,此问题使他的余额为90.

现在该如何处理这个问题。

+0

你说的是闪回,Oracle的临时访问? – 2010-11-01 18:13:25

+0

编号纯SQL更新语句。 – RKh 2010-11-01 18:17:13

+0

您正试图查看来自其他会话的未提交数据?然后在提交之前更新它!? – 2010-11-01 18:25:35

回答

4

我想你想要的是什么反正发生如果你UPDATE

甲骨文确实保留了一段时间的旧数据,但只是为了支持一致的读取。也就是说,读操作只能看到事务开始时的状态 - 即使数据在此期间被覆盖。它被称为多版本并发控制,可以通过事务隔离级别来控制。

您可以通过选择`FOR UPDATE明确要求最近的一个;为记录添加锁定,以便其他人无法在此期间更新它(直到您的交易结束)。

但是,如果您需要编写任何内容(例如,UPDATE),Oracle会在最新版本上运行总是

+0

请检查OP中的实际情况。 – RKh 2010-11-02 08:01:01

+0

我已经在运行,只是通过您的更新掠过。这可能是一个竞争条件?所以我在上面添加了一些关于FOR UPDATE的内容。 – 2010-11-02 08:19:25

1

正如@Markus建议的那样,您有一个竞争条件。如果您在更新表中的行之前将记录加载到内存中并处理它们,并且其他内容可能会在尝试更新它们的同时尝试更新它们,那么您需要在处理它们时锁定它们。 (我假设你正在做的事情太复杂了,不能做一个简单的一步更新)。像这样的东西会工作:

DECLARE 
    CURSOR c is SELECT * FROM current_balance_table FOR UPDATE; 
BEGIN 
    FOR r IN c LOOP 
     /* Do whatever calculations you need */ 
     new_value := r.CurrantAccountBalance - 10; 
     UPDATE current_balance_table SET CurrentAccountBalance = new_value 
     WHERE CURRENT OF c; 
    END LOOP: 
END; 

现在的问题是,所有的记录都被锁定为循环的持续时间,所以你在店内的客户要么无法更新自己的平衡,或将有一个日志在更新生效之前等待 - 尽管如此,它会对您存储的更新值起作用。所以你必须将光标分成小块,平衡脚本的性能和对其他尝试更新同一个表的人的影响。

一种选择是使用外部游标来选择所有未锁定的客户,然后在该行被计算和更新时锁定该客户的余额记录。您必须在每个内部循环之后提交才能释放该行的锁定。这涉及到更多的锁定/解锁和每次行更新后提交减慢了很多事情。但它最大限度地减少了对店内个人客户的影响,因为一次只锁定一行,锁定的时间最短。所以,你需要找到合适的平衡点。

+0

目前我们正在锁定,但我想知道任何有效的替代方案。 – RKh 2010-11-02 09:41:10

相关问题