我想运行此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))
答案 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 - 个别语句总是绑定在他们自己的“隐式事务”中。在列上按下主键约束,您应该完成。
我觉得有必要提一下,如果你的角色列中有非数字值,你会遇到问题......