获取最后一个插入的ID

问题描述:

我正在使用下面的方法获取最后插入的行的ID。获取最后一个插入的ID

Database.ExecuteNonQuery(query, parameters); 

    //if another client/connection inserts a record at this time, 
    //could the line below return the incorrect row ID? 
    int fileid = Convert.ToInt32(Database.Scalar("SELECT last_insert_rowid()")); 
    return fileid; 

这种方法到目前为止工作得很好,但我不确定它是否完全可靠。

假设有两个客户端应用程序,每个客户端应用程序都有自己单独的数据库连接,它们完全同时调用上面的服务器端方法。请记住,客户端线程并行运行,并且SQLite一次只能运行一个操作(或者我听说过),一个客户端实例是否可以返回插入的记录的行ID另一个例子?

最后,有没有更好的方法来获取最后插入的行ID?

如果另一个客户端/连接此时插入一条记录,下面的行是否可以返回不正确的行ID?

不,因为写入要么发生在读取之后,要么发生在读取之后,而是发生在读取之前,而不发生在读取期间。

请记住,客户端线程并行运行,并且SQLite一次只能运行一个操作,一个客户端是否可以获取由另一个客户端插入的记录的行ID ?

是的,当然。

服务器端方法在同一时间调用并不重要。数据库的锁定允许并发读取,但不能并发写入,或写入时读取。

如果你还没有,请阅读SQLite's file locking model

+1

在代码中评论的问题与问题的其余部分一样要求相同的问题。注释行仅用于标记我认为另一个客户端实例可以插入记录的时间。 – rafale 2011-06-15 05:33:48

+0

好的。尽管如此,我们很清楚,注释行并不表示比“SELECT”之前更具体的时间。 – 2011-06-15 05:36:50

+0

是的,“在SELECT之前”是我的意思。我只是不确定你为什么一开始不回答。在读取期间写入不会发生,但是在读取另一个客户端之前可能发生来自一个客户端的写入。该客户端然后将获得由另一个客户端插入的行的ID。理想情况下,我会让SQLite在INSERT之后执行锁定,然后在SELECT之后释放。 – rafale 2011-06-15 05:45:50

如果insert命令和get last inserted row id命令都在同一个写入锁中,并且在这两个命令之间没有其他插入命令可以在这两个命令之间运行,那么您就很安全。

如果您在insert命令之后启动写入锁定,则无法确定另一个线程是否先没有写入锁定。如果另一个线程先得到一个写锁,那么在其他线程释放它们的锁之前,您将无法执行对该行ID的搜索。届时,如果另一个线程插入一个新行就可能为时已晚。