fix(storage): retry a read transaction that fails to begin under load

This commit is contained in:
justme committed 2026-10-16 17:54:30 +08:00
1 parent fb5800f81d
commit 700be2ebae
1 file changed
+15 -5
@@ -51,11 +51,21 @@ public sealed class SqliteChannelStore : IResourceStore, IDisposable
public T Read<T>(Func<IResourceTx, T> action)
{
using var conn = Open();
// 显式事务让一次 Read 内的多条查询看到同一份快照
// 读事务延迟到首次访问时才取快照,避免并发读预检抢占 SQLite 写锁。
using var tx = conn.BeginTransaction(deferred: true);
return action(new SqliteTx(conn));
for (int attempt = 0; ; attempt++)
{
using var conn = Open();
// 显式事务让一次 Read 内的多条查询看到同一份快照
// 读事务延迟到首次访问时才取快照,避免并发读预检抢占 SQLite 写锁。
SqliteTransaction tx;
try { tx = conn.BeginTransaction(deferred: true); }
// 并发压力下偶发 SQLITE_ERROR(CI 的并行追加测试里出现过):丢弃这条连接和池里的闲置连接,换新连接重试
catch (SqliteException e) when (e.SqliteErrorCode == 1 && attempt < 2)
{
SqliteConnection.ClearPool(conn);
continue;
}
using (tx) return action(new SqliteTx(conn));
}
}
public T Write<T>(Func<IResourceTx, T> action)