【发布时间】:2017-12-25 00:16:34
【问题描述】:
我希望通过 Teradata 事务实现等效的快照隔离。 Oracle 支持这种类型的隔离,但 Teradata 不支持(至少在我知道的版本 14 或更早版本中不支持)。目标是创建一个删除表格内容然后重新填充所有内容的过程,同时防止其他用户读取/写入表格。
我遇到了begin request 语句,据我了解,它允许优化器了解请求中的所有各种表锁。
我编写了下面的过程,但不知道如何可靠地调试它,就像我在 .NET 应用程序中测试线程锁定一样简单(易于设置断点和监视其他线程)。在 Teradata 中,不确定我在这里写的内容是否会在整个过程中正确锁定 mydb.destinationtable。这是正确的吗?
编辑:我会补充说该程序确实有效。它只是能够在执行 DELETE/INSERT 时正确地为 SELECT 计时。
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.使用视图而不是表来读取数据。 2. 加载时删除视图。 3. 加载完成后重新创建视图。据我所知,您还可以使用 mload,它会为您处理所有锁定。
-
为什么不使用 TASM 拒绝(或延迟)针对在 ETL 期间加载的表(或数据库)的请求?不是理想的解决方案,但解决了锁隔离问题。或者,您是否可以在最终用户访问表的视图中使用队列表和使用嵌套 SELECT 语句定义的列,该表试图访问队列表中的令牌。如果令牌丢失,查询进入 QT_DELAYED 状态。
-
@RobPaller 在研究 TASM 和查看队列表示例时,似乎涉及很多设置和/或样板。并不是说他们不会工作,而是只是在寻找一种方法,在存储过程中(即,不是 BTEQ 等),1)在表上设置排他锁,2)执行多个语句(甚至不一定反对锁定表),然后 3)释放锁。 dnoeth 的回答 似乎 确认我的 OP 代码会做到这一点,尽管我还不太了解瞬态日志的潜在性能影响。
-
只是关于如何调试行为的建议。创建一个假表,并在您的过程中插入此假表的更新,您通常会在其中设置断点。在启动该过程之前,从另一个会话中锁定假表。这样,您的过程将在您需要的地方阻塞,您可以测试锁定目标表对其他用户的影响。
-
@Insac 我非常喜欢这个想法。我将如何无限期锁定一张桌子?
标签: teradata