2016-11-27 31 views
0

我使用SQLite的last_insert_rowid()來獲取批量插入後最後插入的行ID。是否有任何競爭條件的風險可能導致此值不返回批次插入的最後一個ID?例如,是否有可能在完成插入和調用last_insert_rowid()之間的某個其他進程可能再次寫入表中?在SQLite中檢索批插入行的ID

回答

1

last_insert_rowid()返回有關在此特定連接中完成的最後一次插入的信息;它不能返回其他進程寫入的值。

爲確保返回的值與數據庫的當前狀態相對應,請利用SQLite的ACID保證(此處爲原子性):將批處理插入,last_insert_rowid()調用以及您使用ID進行的任何操作一筆交易。

在任何情況下,last_insert_rowid()的返回值僅在某些插入通過此連接完成時發生更改,因此您絕不應從多個線程訪問同一連接,或者如果您確實想這樣做,請手動序列化整個事務。

+1

@Zso的評論呢?他建議多線程可以使用相同連接的場景。交易會防範嗎? – maxedison

+0

一個連接=一個事務,因此無論線程模式如何,都不應從多個線程訪問相同的連接。 –

+0

這個答案不應該被接受,因爲它談論**進程**,但風險在於使用**線程**。 'last_insert_rowid()'不一定是多線程安全的; 「多線程」線程模式會禁用數據庫連接的禁用。 – Zso

1

last_insert_rowid()是依賴於連接的,所以當多線程使用相同的連接時,如果沒有將SQLite切換到序列化線程模式,就有風險。

+1

串行線程模式如何防範此問題?它是否阻止多個線程使用相同的連接? – maxedison

+0

沒有什麼能阻止你使用多線程,但默認情況下SQLite處於序列化模式。它應該使SQLite線程安全,即使在相同的數據庫連接通過互斥體。 – Zso

+0

您的原始問題表明**進程**,但您似乎對**線程**感興趣。 (數據庫連接不能在進程之間共享。) – Zso