在存储过程中的多个语句期间锁定表

时间:2017-07-19 15:48:46

标签: teradata

我希望用Teradata事务实现快照隔离的等价物。 Oracle支持这种类型的隔离,但Teradata不支持(至少在版本14或之前我不知道)。目标是创建一个删除表内容的过程,然后重新填充所有内容,同时阻止其他用户读取/写入表。

我遇到了begin request语句,根据我的理解,它允许优化器知道请求中的所有各种表锁。

我编写了下面的程序,但是如果我在.NET应用程序中测试线程锁定(易于设置断点和监视其他线程),我不知道如何可靠地调试它。在Teradata中,不确定我在这里写的内容是否会在程序持续时间内正确锁定mydb.destinationtable。这是对的吗?

修改:我将添加该程序确实有效。它只是能够在SELECT执行DELETE / INSERT时正确计时。

replace procedure mydb.myproc()
begin
    begin request

    locking mydb.destinationtable for exclusive
    delete mydb.destinationtable;

    locking mydb.destinationtable for exclusive
    insert into mydb.destinationtable
    select * from mydb.sourcetable;

    end request;
end;

1 个答案:

答案 0 :(得分:0)

BEGIN REQUEST / END REQUEST创建一个所谓的多语句请求(MSR),它与使用F9在SQL Assistant中提交这两个请求相同。

要查看计划,请使用F9:

EXPLAIN
locking mydb.destinationtable for exclusive
delete mydb.destinationtable;

insert into mydb.destinationtable
select * from mydb.sourcetable;

或在BTEQ:

EXPLAIN
locking mydb.destinationtable for exclusive
delete mydb.destinationtable
;insert into mydb.destinationtable
select * from mydb.sourcetable;

顺便说一句,第二次锁是多余的。

<强>但即可。当您运行删除&amp; InsSel作为单一交易都将是Transient Journalled。 比单独的请求慢。

更常见的方法是在视图而不是表格上使用目标表和基本访问的两个副本:

-- no BEGIN/END REQUEST
insert into mydb.destinationtable_2
select * from mydb.sourcetable;

-- there's just a short dictionary lock
-- all requests against the view submitted before the replace use the old data
-- and all submitted after the new data
replace view myview as 
select * from mydb.destinationtable_2;

delete from mydb.destinationtable_1;

现在你的SP只需要在1和1之间切换的逻辑。 2(基于 table [not] empty