询问者
sqlserver事务疑问

问题
-
前提:数据库是sqlserver2012, sqlserver默认事务级别我没有调整
为什么在ado.net中的事务,删除没有锁表,在并行情况下,插入了重复的数据。
数据库中:
create table test( f1 int, f2 datetime )
C# 代码:
private Action<String> writeLogAction; public void Test(Action<String> action) { this.writeLogAction = action; for (var i = 0; i < 5; i++) { Thread thread = new Thread(Exec); thread.Start(); } } private void Exec() { var sql1 = @"delete from test"; var sql1_1 = @"INSERT into test values(1, getdate())"; using (SqlConnection connection = new SqlConnection(connectinString)) { connection.Open(); using (SqlTransaction myTrans = connection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted)) { try { var cmd = new SqlCommand(sql1, connection, myTrans); writeLogAction("start1"); cmd.ExecuteNonQuery(); writeLogAction("end1"); cmd = new SqlCommand(sql1_1, connection, myTrans); cmd.CommandText = sql1_1; cmd.ExecuteNonQuery(); writeLogAction("end2"); // Thread.Sleep(1000100); myTrans.Commit(); writeLogAction("-----------> ok"); } catch (Exception ex) { myTrans.Rollback(); writeLogAction(ex.Message); } } } }
最后执行的结果,每次都不一样:
- 线程数<=3个时,执行完后test表永远只有1条记录
- 线程数> 3时,执行完后test表数据数条数不定,每次都不一样
我的理解是事务内删除整表,整表会被锁定,其他事务应该操作不了非查询的才对,但是实测下来,不是的。
请问各位,是不是哪里我理解错了? 往指正!
全部回复
-
System.Data.IsolationLevel.ReadCommitted:这个级别应该是默认的,它确实不会锁表。它只是保证说你每次读到的记录一定是前一个事务已经提交的。
我建议你尝试使用最高级别Serializable试试看:
https://docs.microsoft.com/zh-cn/dotnet/api/system.data.isolationlevel?redirectedfrom=MSDN&view=netframework-4.8
另外关于SQL SERVER的事务级别:
https://docs.microsoft.com/zh-cn/sql/connect/jdbc/understanding-isolation-levels?view=sql-server-2017
Reproduce your quesions with ScreenToGif is your choice.
For IIS: IIS Forum,
For WebSite of .NET: ASP.NET Forum,
For others: StackExchange.
For spam-sender or forum urgent issues, Send your Email at: forumsfeedback@microsoft.com