我有这个SQL Server 2008 R2表(t1):
+----+------+----------+
| id | type | sequence |
+----+------+----------+
| 1 | 'A' | 1 |
| 2 | 'A' | 2 |
| 3 | 'A' | 3 |
| 4 | 'B' | 1 |
| 5 | 'B' | 2 |
| 6 | 'C' | 1 |
+----+------+----------+
例如,为类型' B'插入下一个序列。必须是3,我用:
void Add(string type)
{
int i = db.ExecuteScalar("select coalesce(max(sequence) + 1, 1) from t1 where type='" + type + "'");
db.ExecuteNonQuery("insert into t1 (type, sequence) values ('" + type + "', " + i + ")");
}
Add("B");
这很好用,但是如果两个用户完全同时执行添加(" B")他们将获得并插入相同的序列!
我应该如何防止这种情况发生?
答案 0 :(得分:1)
您可以添加锁定声明。为了防止死锁,您应该在任务中执行查询。
private static object ExecuteLock = new object();
void Add(string type)
{
Task.Run(() =>
{
lock(ExecuteLock)
{
int i = db.ExecuteScalar("select coalesce(max(sequence) + 1, 1) from t1 where type='" + type + "'");
db.ExecuteNonQuery("insert into t1 (type, sequence) values ('" + type + "', " + i + ")");
}
});
}
Add("B");
这仅在两个用户使用相同的应用程序和相同的应用程序实例插入唯一序列号时才有效。如果两个用户使用不同的应用程序,则需要在数据库级别解决此问题,如注释中所述