【问题标题】:C# SQLite database lockedC# SQLite 数据库锁定
【发布时间】:2018-10-21 14:10:05
【问题描述】:

我已经尝试了所有我能找到的解决这个问题的方法,但由于某种原因,我仍然得到一个异常,说明我正在使用的数据库被锁定。 我的代码如下:

string connectionString = "Data Source=D:\\CCIW\\LCM\\Organisational Database\\OrganisationalDB;" +
                        "MultipleActiveResultSets=True";
using (SQLiteConnection OriginatorDBConnection = new SQLiteConnection(connectionString))
{
    string originatorName, originatorOrganisation, originatorAddress, originatorCellNumber, originatorTelNumber, originatorEmail;

    originatorName = originatorNameTextBox.Text;
    originatorOrganisation = originatorOrganisationTextBox.Text;
    originatorAddress = originatorAddressRichTextBox.Text;
    originatorCellNumber = originatorCellTextBox.Text;
    originatorTelNumber = originatorTelTextBox.Text;
    originatorEmail = originatorEmailTextBox.Text;

    OriginatorDBConnection.Open();
    string originatorINSERT = "INSERT INTO Originator (Name, Organisation, Address, CellphoneNumber, TelephoneNumber, Email) VALUES ('" + originatorName + "', '" + originatorOrganisation + "', '" + originatorAddress + "', '" + originatorCellNumber + "', '" + originatorTelNumber + "', '" + originatorEmail + "');";

    using (SQLiteCommand originatorCommand = new SQLiteCommand(originatorINSERT, OriginatorDBConnection))
    {
        originatorCommand.ExecuteNonQuery();                    
    }
    OriginatorDBConnection.Close();
}

我能找到的最接近问题的解决方案是:SQLite Database Locked exception

但是,它似乎对我的问题不起作用。 我做错了什么?

我有一个使用连接的附加功能:

 public AdminForm()
 {
        //Initialise AdminForm components.
        InitializeComponent();

        //Establish and open connection to ObservationDB.
        string connectionString = "Data Source=D:\\CCIW\\LCM\\Organisational Database\\OrganisationalDB;" +
                                  "MultipleActiveResultSets=True";
        ObservationDBConnection = new SQLiteConnection(connectionString);
        ObservationDBConnection.Open();

        //Query database to find all originators
        string originatorSELECT = "SELECT * FROM Originator;";
        string ECPNumberSELECT = "SELECT * FROM ECP";

        SQLiteCommand command = new SQLiteCommand(originatorSELECT, ObservationDBConnection);
        SQLiteDataReader reader = command.ExecuteReader();

        SQLiteCommand command2 = new SQLiteCommand(ECPNumberSELECT, ObservationDBConnection);
        SQLiteDataReader reader2 = command2.ExecuteReader();

        //Populate OriginatorName combobox with names of existing originators.
        List<string> originatorNames = new List<string>();
        while (reader.Read())
        {
            originatorNames.Add(Convert.ToString(reader["Name"]));
        }

        OriginatorNameComboBox.DataSource = originatorNames;

        //Populate ECP combobox with numbers of existing ECP.
        List<string> ECPNumbers = new List<string>();
        while (reader2.Read())
        {
            ECPNumbers.Add(Convert.ToString(reader2["Number"]));
        }

        ECPNumComboBox.DataSource = ECPNumbers;

        //Populate TC Decision combobox with options.
        List<string> TCDecision = new List<string>();
        TCDecision.Add("Rework");
        TCDecision.Add("Reject");
        TCDecision.Add("Approve");

        TCDecisionComboBox.DataSource = TCDecision;

        ObservationDBConnection.Close();
    }

这里:

private void SaveButton_Click(object sender, EventArgs e)
    {
        ObservationDBConnection.Open();

        ...

        string ImpactTypeINSERT = "INSERT INTO ImpactType (ImpactType, Description) VALUES ('" + impactType + "', '" + impactDescription + "');";
        SQLiteCommand ImpactTypeCommand = new SQLiteCommand(ImpactTypeINSERT, ObservationDBConnection);
        //SQLiteDataReader ImpactTypeReader = ImpactTypeCommand.ExecuteReader();
        ImpactTypeCommand.ExecuteNonQuery();

        ...

        string TCDecisionINSERT = "INSERT INTO TCDecision (Decision, Description) VALUES ('" + TechnicalCommitteeDecision + "', '" + TechnicalCommitteeDescription + "');";
        SQLiteCommand TCDecisionCommand = new SQLiteCommand(TCDecisionINSERT, ObservationDBConnection);
        SQLiteDataReader TCDecisionReader = ImpactTypeCommand.ExecuteReader();
        TCDecisionCommand.ExecuteNonQuery();

        ...

        string OperationalDecisionINSERT = "INSERT INTO OperationalDecision (Decision, Description) VALUES ('" + operationalDecision + "', '" + operationalDescription + "');";
        SQLiteCommand OperationalDecisionCommand = new SQLiteCommand(OperationalDecisionINSERT, ObservationDBConnection);
        //SQLiteDataReader OperationalDecisionReader = OperationalDecisionCommand.ExecuteReader();
        OperationalDecisionCommand.ExecuteNonQuery();

        ...

        ...

            string OriginatorIDSELECT = "SELECT * FROM Originator WHERE Name='" + OriginatorNameComboBox.Text + "';";
            SQLiteCommand OriginatorIDCommand = new SQLiteCommand(OriginatorIDSELECT, ObservationDBConnection);
            SQLiteDataReader OriginatorIDReader = OriginatorIDCommand.ExecuteReader();
            originatorIDOBS = OriginatorIDReader.GetOrdinal("ID");
            //ImpactType
            string impactTypeSELECT = "SELECT * FROM ImpactType WHERE ImpactType='" + impactType + "';";
            SQLiteCommand impactTypeOBSCommand = new SQLiteCommand(impactTypeSELECT, ObservationDBConnection);
            SQLiteDataReader impactTypeOBSReader = impactTypeOBSCommand.ExecuteReader();
            impactTypeOBS = impactTypeOBSReader.GetOrdinal("ID");            

            string operationalDecisionOBSSELECT = "SELECT * FROM OperationalDecision WHERE Decision='" + operationalDecision + "';";
            SQLiteCommand operationalDecisionOBSCommand = new SQLiteCommand(operationalDecisionOBSSELECT, ObservationDBConnection);
            SQLiteDataReader operationalDecisionOBSReader = operationalDecisionOBSCommand.ExecuteReader();
            operationalDecisionOBS = operationalDecisionOBSReader.GetOrdinal("ID");

           ...

            string ECPOBSSELECT = "SELECT * FROM ECP WHERE Number='" + ECPNumComboBox.Text + "';";
            SQLiteCommand ECPCommand = new SQLiteCommand(ECPOBSSELECT, ObservationDBConnection);
            SQLiteDataReader ECPReader = ECPCommand.ExecuteReader();
            ECPOBS = ECPReader.GetOrdinal("ID");


            string CNISObservationINSERT = "INSERT INTO CNISObservation (Title, ReceiveDate, TableDate, OriginatorID, OriginatorReference, OriginatorDate, ObservationNumber, RevisionNumber, Description, Status, ImpactDescription, ImpactType, OperationalRequirementDescription, OperationalImpact, OperationalDecision, ProposedAction, TCDecision, ECP, SolutionOperationalImpact, TechnicalSolutionImpact) VALUES ('" + 
                                                                        titleOBS + "','" 
                                                                        + receiveDateOBS + "','" 
                                                                        + tableDateOBS + "','"
                                                                        + originatorIDOBS + ",'"
                                                                        + originatorReferenceOBS +"','"
                                                                        + originatorDateOBS + "','"
                                                                        + observationNumberOBS + "',"
                                                                        + revisionNumberOBS + ",'"
                                                                        + descriptionOBS + "',"
                                                                        + statusOBS + ",'"
                                                                        + impactDescriptionOBS + "',"
                                                                        + impactTypeOBS + ",'"
                                                                        + operationalRequirementDescriptionOBS + "','"
                                                                        + operationalImpactOBS + "',"
                                                                        + operationalDecisionOBS + ",'"
                                                                        + TCDecisionOBS + ","
                                                                        + ECPOBS + ",'"
                                                                        + solutionOperationalImpactOBS + "','"
                                                                        + technicalSolutionImpactOBS + "');"; 

        ...

        string obsOBSSELECT = "SELECT * FROM CNISObservation ORDER BY ID DESC LIMIT 1;";
        SQLiteCommand CNISObservationIDCommand = new SQLiteCommand(obsOBSSELECT, ObservationDBConnection);
        SQLiteDataReader CNISObservationIDReader = CNISObservationIDCommand.ExecuteReader();
        observationID = CNISObservationIDReader.GetOrdinal("ID");

        ...

        foreach (var capabilityID in capabilitiesSelected)
        {
            string ObservationOperationalCapabilitiesINSERT = "INSERT INTO ObservationOperationalCapabilities (CapabilityID, ObservationID) VALUES (" + capabilityID + "," + observationID + ");";
            SQLiteCommand ObservationOperationalCapabilitiesCommand = new SQLiteCommand(ObservationOperationalCapabilitiesINSERT, ObservationDBConnection);
            // SQLiteDataReader ObservationOperationalCapabilitiesReader = ObservationOperationalCapabilitiesCommand.ExecuteReader();
            ObservationOperationalCapabilitiesCommand.ExecuteNonQuery();

        }

        ...

        string CNISObservationIDSELECT = "SELECT * FROM CNISObservation ORDER BY ID DESC LIMIT 1;";
        SQLiteCommand CNISObservationCommand = new SQLiteCommand(CNISObservationIDSELECT, ObservationDBConnection);
        SQLiteDataReader CNISObservationReader = CNISObservationCommand.ExecuteReader();
        CNISObservationID = CNISObservationReader.GetOrdinal("ID");

        string CNISReleaseINSERT = "INSERT INTO CNISSection VALUES (" + CNISObservationID + "," + CNISRelease + "," + chapter + ",'" + paragraph + "','" + section + "','" + page +"');";
        SQLiteCommand CNISReleaseCommand = new SQLiteCommand(CNISReleaseINSERT, ObservationDBConnection);
        //SQLiteDataReader CNISReleaseReader = CNISReleaseCommand.ExecuteReader();
        CNISReleaseCommand.ExecuteNonQuery();

        ObservationDBConnection.Close();
    }

【问题讨论】:

  • 你确定你的代码中没有其他地方打开它,或者没有其他进程在使用它
  • 我有一个单独的函数在我使用它的地方(虽然代码很长)。但是我确保在执行后关闭连接。这是两个不相交的函数,因此一个可以在另一个之前调用 - 不确定这是否会有所不同。我是否应该发布其他代码的内容以及上下文?
  • 问题是一些 other 连接或程序仍然有一个活动事务,所以 this 代码所做的并不真正相关。
  • 其他代码可能相关,但正如我和@CL 所说,它更有可能是其他代码。虽然如果由于某种原因你的代码在这里导致异常你可能会发现关闭没有被执行..
  • 请参数化您的 SQL - 这对于 SQL 注入来说绝对成熟,因为您正在从用户那里获取输入 - 想象一下如果他们输入 ';DROP TABLE Originator - 这可能允许用户删除您的表

标签: c# visual-studio sqlite


【解决方案1】:

我知道我玩游戏已经很晚了,但看起来你没有在 AdminForm() 构造函数中关闭你的阅读器变量。考虑将 DataReaders 包装在 using() 中。

【讨论】:

    【解决方案2】:

    环绕 Command 和 Reader 确实对我有用:

    using (SqliteCommand cmd = new SqliteCommand(sQuery, m_Conn))
    {
        using (SqliteDataReader reader = cmd.ExecuteReader())
        {
            if (reader.Read())
            {
                ret_type = reader.GetInt32(0);
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      如果SQLite浏览器正在运行并且有任何未保存的更改,请注意点击Write changes
      在我的情况下,我非常愚蠢,我在 SQLite 浏览器中进行更改并且没有单击写入更改,这锁定了要由服务修改的数据库。在我单击“写入更改”按钮后,所有发布请求都按预期工作。

      根据@Rohan Shenoy 在本主题中:SQLite Database Locked exception

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-06
        • 1970-01-01
        • 2011-08-05
        相关资源
        最近更新 更多