正确的SQL命令隔离级别

时间:2014-08-15 13:27:19

标签: sql sql-server database transactions ado.net

我想运行此SQL语句以向Rank表中插入新的排名。主键rank_id是一个char字段,因此它不会自动递增。所以我使用TOP关键字来获取最后一个ID,然后在SQL中增加它。

const string InsertStatement = @"BEGIN DECLARE @ID INT = (SELECT TOP 1 (rank_id + 1) FROM Rank ORDER BY [rank].rank_id DESC) 
                               INSERT INTO RANK (rank_id, rank_name, shift_rate, revised_date) VALUES (@ID, @rank, @rate, @date) END"

我认为我应该处理这个事务以避免脏读,否则另一个用户可能会读错ID作为最后一个。我对么?那么这种情况的正确隔离级别是什么?那怎么样......

using(var Trans = sqlConnection.BeginTransaction(IsolationLevel.Serializable))

1 个答案:

答案 0 :(得分:2)

你可以从SQL端解决这个问题。以下可以解决这个问题:

INSERT RANK (rank_id, rank_name, shift_rate, revised_date)
 select max(rank_id) + 1, @rank, @rate, @date
  from RANK

它是一个单一的语句,因此是一个Atomic事务 - 也就是说,它在表上获得它自己的锁(如果有的话,它就是索引),确保没有其他同时运行的完全相同的查询可以“抓住“下一个价值。

脏读只是不可能的,因为它都是在一个(可能非常快)的语句中完成的。这可以让你获得Atomocity - 个别语句总是绑定在他们自己的“隐式事务”中。在列上按下主键约束,您应该完成。

我觉得有必要提一下,如果你的角色列中有非数字值,你会遇到问题......