在redshift中插入时如何真正锁定表,我认为是这样的,但我不确定aws文档是否总是零输入
begin;lock table sku_stocks;insert into sku_stocks select facility_alias_id, facility_name, CAST( item_name AS bigint), description, CAST( prod_type AS smallint ), total_available, total_allocated from tp_sku_stocks;
1条答案
按热度按时间zbq4xfa01#
LOCK
具有文档化的行为:它获得表上的独占锁,因此其他会话或事务不能对表执行任何操作。如果您希望验证此行为,可以使用以下方法:
打开到数据库的连接并调用
begin
以及lock
针对测试表的命令。打开到数据库的第二个连接,并尝试执行
select
靠着那张table。等到select返回或者您的用户确信
LOCK
行为符合文件规定。执行
rollback
在第一个会话中,这样就不会永久锁定表。更新
根据您的评论,我认为您对交易的工作原理有误解:
启动事务时,redshift将分配事务id,并标记该事务更改的每一行。
选择在事务中更新表时读取该表将看到“已提交数据的快照”(引用自上面的链接),而不是事务中正在更新的行。
尝试更新由事务更新的表的insert/update/delete将被阻塞,直到事务完成为止(请参阅doc,请注意,这种行为与您在mysql中看到的有些不同)。
提交/回滚事务时,任何新的选择都将使用更新的数据。在事务期间启动的任何选择都将继续使用旧数据。
根据这些规则,几乎没有理由使用显式lock语句。您的示例update(不带锁)将在被更新的表上设置一个写锁(这样可以确保没有其他查询可以同时更新它),并将使用它正在读取的表的快照。
如果使用了锁,则会阻止在更新期间尝试从表中选择的任何查询。您可能认为这是您想要的,以确保您的用户只看到最新的数据,但考虑到这一点,在更新之前启动的任何选择仍将看到旧数据。
我使用lock语句的唯一原因是,如果您需要维护一组表之间的一致性(当然,如果您正进入死锁,但您没有指出这一点):
在这种情况下,您可以确保表1、表2和表3始终保持一致:对其中任何一个表的查询都将显示相同的信息。但是,请注意,选择在锁定成功之前启动的,并在任何更新之前显示数据。并选择在事务期间启动直到事务完成才实际执行。你的用户可能不喜欢这样,如果它发生在他们的工作日中间。