none
sqlserver事务疑问 RRS feed

  • 问题

  • 前提:数据库是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表数据数条数不定,每次都不一样

    我的理解是事务内删除整表,整表会被锁定,其他事务应该操作不了非查询的才对,但是实测下来,不是的。

    请问各位,是不是哪里我理解错了? 往指正!

    2019年10月23日 3:15

全部回复

  •  一个进程(session_id or spid)里,锁是不会阻塞自己的

    SQL Server 2016 ~ 2000 性能优化、方案设计 QQ:315054403 田园嘉兴

    2019年10月23日 5:52
  • 你说的一个进程是数据库的进程吗?

    我这里多个线程,每个线程有单独的连接和事务,这个是在一个spid中?

    2019年10月23日 6:00
  • 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

    2020年2月13日 6:47