Skip to content

Commit db73e8f

Browse files
committed
improve sqlite concurrency problem (dotnetcore#260)
1 parent e5294b8 commit db73e8f

File tree

1 file changed

+34
-14
lines changed

1 file changed

+34
-14
lines changed

src/EasyCaching.SQLite/Configurations/SQLiteDatabaseProvider.cs

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
{
33
using EasyCaching.Core;
44
using Microsoft.Data.Sqlite;
5-
using Microsoft.Extensions.Options;
5+
using System.Collections.Concurrent;
6+
using System.Data;
7+
using System.Threading;
8+
using System.Threading.Tasks;
69

710
/// <summary>
811
/// SQLite database provider.
@@ -16,16 +19,27 @@ public class SQLiteDatabaseProvider : ISQLiteDatabaseProvider
1619

1720
public SQLiteDatabaseProvider(string name , SQLiteOptions options)
1821
{
19-
this._name = name;
20-
this._options = options.DBConfig;
22+
_name = name;
23+
_options = options.DBConfig;
24+
_builder = new SqliteConnectionStringBuilder
25+
{
26+
DataSource = _options.DataSource,
27+
Mode = _options.OpenMode,
28+
Cache = _options.CacheMode
29+
};
30+
31+
_conns = new ConcurrentDictionary<int, SqliteConnection>();
2132
}
2233

34+
private static ConcurrentDictionary<int, SqliteConnection> _conns;
35+
2336
/// <summary>
24-
/// The conn.
37+
/// The builder
2538
/// </summary>
26-
private static SqliteConnection _conn;
39+
private static SqliteConnectionStringBuilder _builder;
2740

2841
private readonly string _name = EasyCachingConstValue.DefaultSQLiteName;
42+
2943
public string DBProviderName => _name;
3044

3145
/// <summary>
@@ -34,19 +48,25 @@ public SQLiteDatabaseProvider(string name , SQLiteOptions options)
3448
/// <returns>The connection.</returns>
3549
public SqliteConnection GetConnection()
3650
{
37-
if(_conn == null)
51+
var threadId = Thread.CurrentThread.ManagedThreadId;
52+
var con = _conns.GetOrAdd(threadId, CreateNewConnection());
53+
54+
Task.Run(async () =>
3855
{
39-
SqliteConnectionStringBuilder builder = new SqliteConnectionStringBuilder()
56+
await Task.Delay(5000).ConfigureAwait(false);
57+
_conns.TryRemove(threadId, out var removingConn);
58+
if (removingConn?.State == ConnectionState.Closed)
4059
{
41-
DataSource = _options.DataSource,
42-
Mode = _options.OpenMode,
43-
Cache = _options.CacheMode
44-
};
60+
removingConn.Dispose();
61+
}
62+
});
4563

46-
_conn = new SqliteConnection(builder.ToString());
64+
return con;
65+
}
4766

48-
}
49-
return _conn;
67+
private SqliteConnection CreateNewConnection()
68+
{
69+
return new SqliteConnection(_builder.ToString());
5070
}
5171
}
5272
}

0 commit comments

Comments
 (0)