2015-01-14 58 views
2

我期望sqlite會丟棄已使用和回滾(ed)的PK值,但不會發生這種情況。這裏是測試:sqlite在回滾後重復主鍵自動增量值

PRAGMA foreign_keys = ON; 
BEGIN TRANSACTION; 
INSERT INTO _UIDlgt (id, TS) VALUES (null, '1421248181'); 
select max(id) from _UIDlgt;   -- shows 6 ok, there were previous records 
ROLLBACK; 
select max(id) from _UIDlgt;   -- shows 5 ok, was previous max value 
INSERT INTO _UIDlgt (id, TS) VALUES (null, '1421248181'); 
select max(id) from _UIDlgt;   -- shows 6 I expect 7 !!!! 

這是創建表:

CREATE TABLE _UIDlgt (
    id    INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
    TS    INTEGER NOT NULL 
); 

手冊says未能插入跳過的PK值嘗試使用,但注意到有關回滾。
現在的問題是:有沒有一些設置來管理這種行爲?還是個詭計?

Ms Sql Server按我期望的方式工作。 Sqlite版本是PHP 5.4.11下的3.7.7.1

+0

回滾將刪除所有掛起的寫入操作,並且自動增量是對特殊「sqlite_sequence」表的寫入操作。因此,它的值更改僅適用於提交。 – keltar

回答

3

SQLite docs中有一些微妙的語言。 (強調)

換言之,AUTOINCREMENT的目的是爲了防止從先前刪除的行的ROWIDs 的重用 。

這有點不同於客戶端/服務器SQL dbms,它必須處理併發寫入。 SQLite需要一個exclusive lock for writes

隨着AUTOINCREMENT,與自動選擇的ROWIDs行 保證具有的ROWIDs從未被在同一數據庫中使用之前由同一 表。

這意味着保證與提交的行有關。這意味着未提交行的id號在表中並不是「之前使用」(在這個意義上)。

然而,如果插入失敗,因爲(例如)唯一性約束 ,失敗嘗試插入的ROWID可能不能 重用在隨後的插入,從而在ROWID序列空位。

讓開放的可能性重用。

+0

我按照您在此處講述的相同方式解讀本手冊。所以簡短的答案是「沒有辦法」... –