我们的应用程序遇到了麻烦,这个应用程序同时被近500人使用。它是一个Windows桌面应用程序,它在后台使用单个数据库来存储数据。似乎有时会出现一些我们无法再现的竞争条件。当选择更新错误的ID时,例如更新错误的数据。
protected static void ExecuteNonQuery(MySqlConnection connection, String statement, OptionalOut<int> outResult = null)
{
var cmd = connection.CreateCommand();
var cmd2 = connection.CreateCommand();
cmd.CommandText = statement;
cmd.CommandTimeout = 30;
MySqlTransaction tran = null;
MySqlDataReader reader = null;
try
{
connection.Open();
tran = connection.BeginTransaction(IsolationLevel.Serializable);
cmd.ExecuteNonQuery();
if (statement.ToUpper().StartsWith("INSERT INTO"))
{
if (outResult == null) outResult = new OptionalOut<int>();
cmd2.CommandText = "SELECT LAST_INSERT_ID() AS last_ID";
cmd2.CommandTimeout = 30;
reader = cmd2.ExecuteReader();
var ret = ConvertToDataSet(reader);
var cells = ret.Tables[0].Rows[0][0];
outResult.Result = Convert.ToInt32(cells);
reader.Close();
}
tran.Commit();
connection.Close();
}
catch (Exception e)
{
if (reader != null && !reader.IsClosed)
reader.Close();
if (tran != null && connection.State != ConnectionState.Closed && connection.State != ConnectionState.Broken)
tran.Rollback();
connection.Close();
throw;
}
}
这种方法有问题吗?我是否需要一些额外的锁定机制或参数IsolationLevel.Serializable
是否足够?我需要做些什么来防止种族条件的每一种可能情况?
编辑:另一个奇怪的问题是,当一行正在更新并且某些内容失败时,其他列会被更改,但不会受到影响。这是随机发生的,一般来说SQL工作正常!
例如,客户获得要约(要约是客户表中的外键),要约状态从None
切换到OfferReceived
。员工接受要约并保存,数据库中的客户行不再有报价,报价状态切换为OfferAccepted
。对此有任何解释吗?