使用Dapper和Sqlite获取新插入行ID的并发安全性疑问
Dapper和Sqlite获取新插入行ID的并发安全性疑问
我发现以下Sqlite语句可以在Dapper中获取插入的ID,但在并发场景下这安全吗?
string sql = @" insert into MyTable values (null, @name); select last_insert_rowid();";
嘿,这是个很实用的问题!咱们把这个事儿说清楚——你这段用Dapper结合Sqlite获取插入ID的代码,在并发场景下是完全安全的,核心原因和Sqlite的机制以及你的写法有关:
- Sqlite的
last_insert_rowid()是连接隔离的:这个函数的返回值和当前数据库连接绑定,只会返回当前连接上最后一次插入操作生成的行ID。哪怕有N个并发请求同时往数据库插数据,每个连接的last_insert_rowid()结果都是独立的,不会被其他连接的插入操作干扰。 - 你的SQL是原子性的批处理操作:你把
insert和select last_insert_rowid()放在同一个SQL字符串里,Dapper会把这整个语句作为一个整体发送给Sqlite执行。这就彻底避免了“插入后、查询前”被其他操作打断的可能——哪怕是同一个连接里的其他操作,也没法插进来影响结果,因为这是一个连续的执行单元。
举个直观的例子:如果有两个线程分别用各自的数据库连接执行这段代码,线程A插入后拿到ID 100,线程B插入后拿到ID 101,绝对不会出现线程A拿到101、或者线程B拿到100的情况,完全不会串号。
反过来,如果是把insert和select last_insert_rowid()拆成两个独立的Dapper调用,那反而会有风险(比如同一个连接里插入后,被其他操作插队,导致拿到错误的ID),但你现在的写法完美规避了这个问题。
备注:内容来源于stack exchange,提问作者Rod
相关产品推荐
相关产品推荐

