C#中的简单SQLite ORM,代码可以工作,但如何解决竞争条件

C#中的简单SQLite ORM,代码可以工作,但如何解决竞争条件,c#,linq,sqlite,orm,C#,Linq,Sqlite,Orm,为了练习C#编程,我使用创建了这个简单的SQLite查询编写器+ORM,并编写了一些单元测试(使用),以确保代码正常工作。问题是,当我单独运行每个单元测试时,所有单元测试都可以运行,但如果我同时进行所有测试,代码就会失败,并表示数据库被锁定或代码进入无限循环 我想知道是否有办法使用lock(variable){}使代码线程安全,我不确定。也许我处理事务的方式有问题(我只对INSERT语句使用事务) 这就是我认为有问题的功能。任何帮助或反馈都将不胜感激 /// <summary> //

为了练习C#编程,我使用创建了这个简单的SQLite查询编写器+ORM,并编写了一些单元测试(使用),以确保代码正常工作。问题是,当我单独运行每个单元测试时,所有单元测试都可以运行,但如果我同时进行所有测试,代码就会失败,并表示数据库被锁定或代码进入无限循环

我想知道是否有办法使用
lock(variable){}
使代码线程安全,我不确定。也许我处理事务的方式有问题(我只对
INSERT
语句使用事务)

这就是我认为有问题的功能。任何帮助或反馈都将不胜感激

/// <summary>
/// Helper function that creats SQL commands
/// </summary>
/// <param name="commandText"></param>
/// <returns></returns>
private void CreateAndExecuteNonQueryCommand(string commandText)
{
    if (SqliteConnection.State != ConnectionState.Open)
    {
        SqliteConnection.Open();
    }

    var transaction = SqliteConnection.BeginTransaction();
    var command = SqliteConnection.CreateCommand();
    command.Transaction = transaction;

    Transactions.Add(transaction);

    try
    {             
        command.CommandText = commandText;
        command.ExecuteNonQuery();
    }
    catch (Exception e)
    {
        throw new ArgumentException(e?.Message);
    }
    finally
    {
        transaction.Commit();
        transaction.Dispose();
        command.Dispose();
    }
}
//
///创建SQL命令的助手函数
/// 
/// 
/// 
私有void CreateAndExecuteNonQueryCommand(字符串commandText)
{
if(SqliteConnection.State!=ConnectionState.Open)
{
SqliteConnection.Open();
}
var transaction=SqliteConnection.BeginTransaction();
var command=SqliteConnection.CreateCommand();
command.Transaction=事务;
交易。添加(交易);
尝试
{             
command.CommandText=CommandText;
command.ExecuteNonQuery();
}
捕获(例外e)
{
抛出新的ArgumentException(e?.Message);
}
最后
{
Commit();
transaction.Dispose();
command.Dispose();
}
}

代码有点长,直到我写这个问题时的最后一次提交。

SqliteStorage.cs包含方法
public T RetrieveModel(Dictionary keyValueDictionary)
。在这里,您使用
CreateCommand
方法,然后调用
ExecuteReader()但此读卡器未关闭。只需添加这个字符串
reader.Dispose()位于
RetrieveModel
的底部。要避免这种情况,可以使用
using
块。它会自动调用
Dispose

在哪里关闭
SqliteConnection
?我同意,这实际上可能不是竞争条件,而是每个单元测试之间未正确清理的资源。单元测试通常不会并行运行,除非明确要求这样做,因为它可能会导致意外的、难以重现的副作用。最终执行事务提交的意义是什么?您不在乎是否发生异常,是否仍要尝试提交?