sql - 锁表红移
问题描述
插入红移时如何对表进行真正的锁定,我认为是这样,但我不确定并且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;
解决方案
LOCK
有一个记录在案的行为:它在表上获得一个排他锁,因此没有其他会话或事务可以对表做任何事情。
如果您希望验证此行为,请按以下步骤操作:
- 打开到数据库的连接并针对您的测试表调用
begin
and命令。lock
- 打开到数据库的第二个连接,并尝试
select
对该表执行操作。 - 等到选择返回或您确信其
LOCK
行为符合记录。 - 在第一个会话中执行 a
rollback
,这样您就不会永久锁定表。
更新
根据您的评论,我认为您对交易的工作方式有误解:
- 当您启动事务时,Redshift 会分配一个事务 ID,并标记该事务更改的每一行。
- 在事务中更新表时读取表的 SELECT 将看到“已提交数据的快照”(引用来自上面的链接),而不是事务中正在更新的行。
- 尝试更新由事务更新的表的 INSERT/UPDATE/DELETE 将阻塞,直到事务完成(请参阅doc,并注意此行为与您从 MySQL 中看到的有所不同)。
- 当您提交/回滚事务时,任何新的 SELECT 都将使用更新的数据。在事务期间启动的任何 SELECT 将继续使用旧数据。
鉴于这些规则,几乎没有理由使用显式 LOCK 语句。您的示例更新,没有 LOCK,将在正在更新的表上放置一个写锁(因此保证没有其他查询可以同时更新它),并将使用它正在读取的表的快照。
如果您确实使用了 LOCK,您将阻止在更新期间尝试从表中进行 SELECT 的任何查询。您可能认为这是您想要的,以确保您的用户只能看到最新数据,但考虑到这一点,在更新之前启动的任何 SELECT 仍将看到旧数据。
我会使用 LOCK 语句的唯一原因是如果您需要保持一组表之间的一致性(好吧,如果您遇到死锁,但您没有指出这一点):
begin;
lock TABLE1;
lock TABLE2;
lock TABLE3;
copy TABLE1 from ...
update TABLE2 select ... from TABLE1
update TABLE3 select ... from TABLE2
commit;
在这种情况下,您要确保 TABLE1、TABLE2 和 TABLE3 始终保持一致:针对其中任何一个的查询将显示相同的信息。但是请注意,在锁定之前启动的 SELECTS 将成功,并在任何更新之前显示数据。并且在事务期间启动的 SELECT 直到事务完成才会真正执行。如果它发生在工作日中间,您的用户可能不喜欢这种情况。
推荐阅读
- sql - 从组中强制转换的 SQL 查询
- swift - 调用下标 [Swift] 中没有完全匹配
- pytorch - Open3D-ML 和 pytorch
- regex - 在 hive 上第 n 次出现分隔符之前获取所有内容
- reactjs - react-window 元素类型无效:期望字符串(用于内置组件)或类/函数(用于复合组件)但得到:对象
- kotlin - 在 kotlin 中创建 gradle 插件时如何解决 kotlin 库中的冲突
- c++ - 在 C++ 中除以变量与除以 const 时性能下降
- python - 如何直接在 GPU 上或在另一个张量的设备上创建张量?
- c++ - 具有虚函数的静态多态性
- manim - Manim v0.2.0 self.play() 方法