jeudi 28 mai 2015

Sqlite: Are updates to two tables within an insert trigger atomic?

I refactored a table that stored metadata and (large) data in each row into two tables, so that metadata can be queried efficiently.

I also created an updatable view that returns both the data and metadata together, using sqlite's insert, update and delete triggers. This allows calling code that needs both data and metadata to remain unchanged.

The insert and update triggers write each incoming row as two rows - one in the metadata table and one in the data table, like this:

// 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;

Questions:

  • Are the updates to the ItemMetadata and ItemData tables atomic? Is there a chance that a reader can see the result of the first update before the second update has completed?
  • Originally I had the WHERE clauses be WHERE rowid=old.rowid but that seemed to cause random problems so I changed them to WHERE Id=old.Id. The original version was based on tutorial code I found. But after thinking about it I wonder how sqlite even comes up with an old rowid - after all, this is a view across multiple tables. What rowid does sqlite pass to an update trigger, and is the WHERE clause the way I first coded it problematic?

Aucun commentaire:

Enregistrer un commentaire