Sqlite:插入触发器中两个表的更新是原子的吗?
Sqlite: Are updates to two tables within an insert trigger atomic?
我重构了一个 table,将元数据和数据存储到两个 table 中,一个用于元数据,一个用于数据。这允许有效地查询元数据。
我还使用 sqlite 的插入、更新和删除触发器创建了一个包含原始 table 列的 updatable 视图。这允许需要数据和元数据的调用代码保持不变。
插入和更新触发器将每个传入行写入两行 - 一行在元数据 table 中,另一行在数据 table 中,如下所示:
// View
CREATE VIEW IF NOT EXISTS Item as select n.Id, n.Title, n.Author, c.Content
FROM ItemMetadata n, ItemData c where n.id = c.Id
// Trigger
CREATE TRIGGER IF NOT EXISTS item_update
INSTEAD OF UPDATE OF id, Title, Author, Content ON Item
BEGIN
UPDATE ItemMetadata
SET Title=NEW.Title, Author=NEW.Author
WHERE Id=old.Id;
UPDATE ItemData SET Content=NEW.Content
WHERE Id=old.Id;
END;
问题:
- ItemMetadata 和 ItemData table 的更新是原子的吗? reader 是否有可能在第二次更新完成之前看到第一次更新的结果?
- 最初我将 WHERE 子句设置为
WHERE rowid=old.rowid
,但这似乎会导致随机问题,因此我将它们更改为 WHERE Id=old.Id
。原始版本基于我找到的教程代码。但仔细想想,我想知道 sqlite 是怎么想出一个旧的 rowid 的——毕竟,这是一个跨多个 table 的视图。 sqlite 将什么 rowid 传递给更新触发器,WHERE 子句是不是我第一次编码的方式有问题?
No changes can be made to the database except within a transaction. Any command that changes the database (basically, any SQL command other than SELECT) will automatically start a transaction if one is not already in effect.
触发器中的命令被视为触发触发器的命令的一部分。
所以触发器中的所有命令都是事务的一部分,并且是原子的。
视图没有(可用的)rowid
。
我重构了一个 table,将元数据和数据存储到两个 table 中,一个用于元数据,一个用于数据。这允许有效地查询元数据。
我还使用 sqlite 的插入、更新和删除触发器创建了一个包含原始 table 列的 updatable 视图。这允许需要数据和元数据的调用代码保持不变。
插入和更新触发器将每个传入行写入两行 - 一行在元数据 table 中,另一行在数据 table 中,如下所示:
// View
CREATE VIEW IF NOT EXISTS Item as select n.Id, n.Title, n.Author, c.Content
FROM ItemMetadata n, ItemData c where n.id = c.Id
// Trigger
CREATE TRIGGER IF NOT EXISTS item_update
INSTEAD OF UPDATE OF id, Title, Author, Content ON Item
BEGIN
UPDATE ItemMetadata
SET Title=NEW.Title, Author=NEW.Author
WHERE Id=old.Id;
UPDATE ItemData SET Content=NEW.Content
WHERE Id=old.Id;
END;
问题:
- ItemMetadata 和 ItemData table 的更新是原子的吗? reader 是否有可能在第二次更新完成之前看到第一次更新的结果?
- 最初我将 WHERE 子句设置为
WHERE rowid=old.rowid
,但这似乎会导致随机问题,因此我将它们更改为WHERE Id=old.Id
。原始版本基于我找到的教程代码。但仔细想想,我想知道 sqlite 是怎么想出一个旧的 rowid 的——毕竟,这是一个跨多个 table 的视图。 sqlite 将什么 rowid 传递给更新触发器,WHERE 子句是不是我第一次编码的方式有问题?
No changes can be made to the database except within a transaction. Any command that changes the database (basically, any SQL command other than SELECT) will automatically start a transaction if one is not already in effect.
触发器中的命令被视为触发触发器的命令的一部分。 所以触发器中的所有命令都是事务的一部分,并且是原子的。
视图没有(可用的)rowid
。