我目前正在使用下面的方法来获取最后插入的行的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?
答案 0 :(得分:6)
如果此时另一个客户端/连接插入记录,下面的行可能会返回错误的行ID吗?
不,因为写入将在读取之后或读取之前发生,而不是在读取期间发生。
请记住,客户端线程并行运行,并且SQLite一次只能运行一个操作,一个客户端是否可以获取另一个客户端插入的记录的行ID?
是的,当然。
在完全相同的时间调用服务器端方法并不重要。数据库的锁定允许并发读取,但不是并发写入,也不是写入时读取。
如果您还没有,请阅读SQLite's file locking model。
答案 1 :(得分:2)
如果insert命令和get last inserted row id命令都在同一个写锁内,并且该写锁中没有其他insert命令可以在这两个命令之间运行,那么你就是安全的。
如果在insert命令之后启动写锁定,则无法确定另一个线程没有先获得写锁定。如果另一个线程首先获得了写入锁定,那么在其他线程释放其锁定之前,您将无法执行行id的搜索。到那时,如果另一个线程插入一个新行,可能为时已晚。