Sqlite:对insert中的两个表的更新是否触发原子?

时间:2015-05-28 15:36:25

标签: sqlite view triggers atomic rowid

我重构了一个表,它将元数据和数据存储到两个表中,一个用于元数据,一个用于数据。这样可以有效地查询元数据。

我还使用sqlite的insert,update和delete触发器创建了一个包含原始表列的可更新视图。这允许调用需要数据和元数据的代码保持不变。

插入和更新触发器将每个传入的行写为两行 - 一个在元数据表中,一个在数据表中,如下所示:

// 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表的更新是否是原子的?在第二次更新完成之前,读者是否有可能看到第一次更新的结果?
  • 最初我将WHERE子句设为WHERE rowid=old.rowid,但这似乎会导致随机问题,因此我将其更改为WHERE Id=old.Id。原始版本基于我找到的教程代码。但在考虑之后我想知道sqlite是如何提出一个旧的rowid - 毕竟,这是一个跨多个表的视图。什么rowid sqlite传递给更新触发器,并且是我第一次编码它的方式有问题的WHERE子句?

1 个答案:

答案 0 :(得分:1)

documentation说:

  

除了在事务中,不能对数据库进行任何更改。任何更改数据库的命令(基本上,除SELECT之外的任何SQL命令)都将自动启动事务(如果尚未生效)。

触发器中的命令被视为触发触发器的命令的一部分。 因此,触发器中的所有命令都是事务的一部分,而且是原子。

视图没有(可用)rowid