1

我刚刚开始深入研究 Teradata 的锁定功能,而 Google 对此的解释相当复杂。希望我能从 SE 得到一个非常简单和精简的答案。

在遇到 Teradata 中标识列的许多问题后,我决定创建一种模仿 Oracle 序列的机制。为此,我正在创建一个包含两个字段的表,一个包含表名,另一个存储其最后使用的序列。然后,我将创建一个采用表名的存储过程。在此过程中,它将执行以下选项:

  • 从序列表中选择最后使用的序列到一个变量中(select LastId from mydb.sequence where tablename = :tablename
  • 将 1 加到变量的值上,从而增加它
  • 更新序列表以使用增量值
  • 将序列变量返回到过程的 OUT 参数,以便我可以在我的 .NET 应用程序中访问序列 ID

当所有这些操作都在进行时,我需要为所有读写访问锁定序列表,以确保对过程的其他调用不会在当前正在排序的过程中尝试对表进行排序。这显然是为了防止相同的序列在同一张表中被使用两次。

如果这是.NET,我会使用Sync Lock(VB.NET)或lock(C#)来阻止其他线程进入代码块,直到当前线程完成。我想知道是否有一种方法可以像锁定.NET 中的线程一样锁定表。

4

1 回答 1

1

考虑为事务的行哈希锁使用显式锁定机制:

BEGIN TRANSACTION;

LOCKING ROW EXCLUSIVE
SELECT LastId + 1 INTO :LastID
FROM MyDB.SequenceCols
WHERE TableName = :TableName
  AND DatabaseName = :DatabaseName;

UPDATE MyDB.SequenceCols
SET LastId = :LastID
WHERE TableName = :TableName
  AND DatabaseName = :DatabaseName;

END TRANSACTION;

rowhash 锁将允许其他进程针对其他表使用该过程。要确保行级锁定,您必须完全限定 SequenceCols 表的主索引。事实上,SequenceCols 表的主索引应该是 UNIQUE onDatabaseNameTableName

编辑:

排他行哈希锁将阻止另一个进程读取该行,直到 END TRANSACTION 被处理为行哈希锁的所有者。

于 2012-07-31T16:46:53.600 回答