Stored procedures 如何锁定一个表进行读写操作,以便执行SQL,然后移除锁?

Stored procedures 如何锁定一个表进行读写操作,以便执行SQL,然后移除锁?,stored-procedures,locking,teradata,Stored Procedures,Locking,Teradata,我刚刚开始深入研究Teradata的锁定功能,Google对此的解释相当复杂。希望我能从SE那里得到一个非常简单和精简的答案 在Teradata中的标识列遇到许多问题后,我决定创建一种模仿Oracle序列的机制。为此,我创建了一个包含两个字段的表,一个字段保存表名,另一个字段存储上次使用的序列。然后我将创建一个采用表名的存储过程。在程序中,它将执行以下选项: 从序列表中选择上次使用的序列,并将其放入变量Select LastId from mydb.sequence中,其中tablename=:

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

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

从序列表中选择上次使用的序列,并将其放入变量Select LastId from mydb.sequence中,其中tablename=:tablename 将1添加到变量的值,从而使其递增 更新序列表以使用递增的值 将序列变量返回到过程的OUT参数,以便我可以在.NET应用程序中访问序列ID 当所有这些操作都在进行时,我需要为所有读写访问锁定序列表,以确保对该过程的其他调用不会在该表当前正在排序的过程中尝试对其排序。这显然是为了防止相同的序列在同一个表中使用两次


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

考虑对事务的rowhash锁使用显式锁定机制:

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表的主索引在DatabaseName和TableName上应该是唯一的

编辑:


排他rowhash锁将阻止另一个进程读取该行,直到结束事务被处理为rowhash锁的所有者

考虑对事务的rowhash锁使用显式锁定机制:

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表的主索引在DatabaseName和TableName上应该是唯一的

编辑:


排他rowhash锁将阻止另一个进程读取该行,直到结束事务被处理为rowhash锁的所有者

如果同时调用此过程两次,并且两次调用都选择了相同的ID,然后两次调用中的任何一次都无法进行更新,会发生什么情况?请参阅编辑以了解排他rowhash锁的其他解释。因此,我让所有调用都能正常工作。有没有办法测试此锁定是否有效?我自然而然地想到了让存储过程等待的方法,这样我就有足够的时间发送另一个请求,但研究表明,只有UDF能够做到这一点。您可以使用BTEQ和.OS命令在存储过程之外测试逻辑,以调用在提交END TRANSACTION命令之前休眠一段时间的脚本。这将允许您调用第二个进程,该进程尝试使用睡眠进程持有的存储过程为同一个表分配新的标识值。好的,您已经挣到了工资,所以我将标记您的答案!如果同时调用此过程两次,并且两次调用都选择了相同的ID,然后两次调用中的任何一次都无法进行更新,会发生什么情况?请参阅编辑以了解排他rowhash锁的其他解释。因此,我让所有调用都能正常工作。有没有办法测试此锁定是否有效?我自然而然地想到了让存储过程等待的方法,这样我就有足够的时间发送另一个请求,但研究表明,只有UDF能够做到这一点。您可以使用BTEQ和.OS命令在存储过程之外测试逻辑,以调用在提交END TRANSACTION命令之前休眠一段时间的脚本。这将允许您调用第二个进程,该进程尝试使用睡眠进程持有的存储过程为同一个表分配新的标识值。好的,您已经挣到了工资,所以我将标记您的答案!