SQLServer 超时测试研究

SQLServer 超时测试研究,第1张

概述考虑常见的几种前端超时情况测试: 1. 命令超时:执行语句超时 2. 命令超时:未提交事务超时 3. 后台 kill 该连接 4. 网络延迟或丢包 5. 死锁 【命令超时:执行语句超时】 在代码中设置超时时间5秒,同时执行的sql语句中也编写脚本等待5秒; using System;using System.Data.SqlClient;namespace dbConnectionTest

考虑常见的几种前端超时情况测试:

1. 命令超时:执行语句超时

2. 命令超时:未提交事务超时

3. 后台 kill 该连接

4. 网络延迟或丢包

5. 死锁



【命令超时:执行语句超时】
在代码中设置超时时间5秒,同时执行的SQL语句中也编写脚本等待5秒;

using System;using System.Data.sqlClIEnt;namespace dbConnectionTest{    class Program    {        static voID Main(string[] args)        {            string connstring = @"Data source=1card1-hzc;Integrated Security=sspI;Initial Catalog=DemoDB";            string sqlstring = "waitfor delay '00:00:05';SELECT [name],[value] FROM dbo.TestTab";            using (sqlConnection conn = new sqlConnection(connstring))            {                try                {                    sqlCommand cmd = new sqlCommand(sqlstring,conn);                    cmd.CommandTimeout = 5;//命令超时时间                    Console.Writeline("CommandTimeout: {0}",cmd.CommandTimeout);                    conn.open();                    sqlDataReader r = cmd.ExecuteReader();                    Console.Writeline("name       value");                    while (r.Read())                        Console.Writeline("{0}      {1}",r[0].ToString(),r[1].ToString());                }                catch (sqlException se)                {                    Console.Writeline(se);                }                finally                {                    conn.Close();                }                Console.Readline();            }        }    }}

结果错误如下:

CommandTimeout: 5System.Data.sqlClIEnt.sqlException (0x80131904): Timeout 时间已到。在 *** 作完成之前超时时间已过或服务器未响应。 ---> System.ComponentModel.Win32Exception (0x80004005): 等待的 *** 作过时。   在 System.Data.sqlClIEnt.sqlConnection.OnError(sqlException exception,Boolean breakConnection,Action`1 wrapCloseInAction)   在 System.Data.sqlClIEnt.sqlInternalConnection.OnError(sqlException exception,Action`1 wrapCloseInAction)   在 System.Data.sqlClIEnt.TdsParser.ThrowExceptionAnDWarning(TdsParserStateObject stateObj,Boolean callerHasConnectionLock,Boolean asyncclose)   在 System.Data.sqlClIEnt.TdsParser.TryRun(RunBehavior runBehavior,sqlCommand cmdHandler,sqlDataReader dataStream,BulkcopySimpleResultSet bulkcopyHandler,TdsParserStateObject stateObj,Boolean& dataReady)   在 System.Data.sqlClIEnt.sqlDataReader.TryConsumeMetaData()   在 System.Data.sqlClIEnt.sqlDataReader.get_MetaData()   在 System.Data.sqlClIEnt.sqlCommand.FinishExecuteReader(sqlDataReader ds,RunBehavior runBehavior,String resetOptionsstring)   在 System.Data.sqlClIEnt.sqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,Boolean returnStream,Boolean async,Int32 timeout,Task& task,Boolean asyncWrite,sqlDataReader ds)   在 System.Data.sqlClIEnt.sqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,String method,taskcompletionsource`1 completion,Boolean asyncWrite)   在 System.Data.sqlClIEnt.sqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,String method)   在 System.Data.sqlClIEnt.sqlCommand.ExecuteReader(CommandBehavior behavior,String method)   在 System.Data.sqlClIEnt.sqlCommand.ExecuteReader()   在 dbConnectionTest.Program.Main(String[] args) 位置 e:\Tempfile\SSIS\ConnectPoolTest\ConnectPoolTest\Program.cs:行号 20ClIEntConnectionID:8bef8555-f818-49fb-b0ba-473d7a31191a

【命令超时:未提交事务超时】

代码还是上面的代码。执行的 sql 脚本 和 超时设置如下。

string sqlstring = "SELECT [name],[value] FROM dbo.TestTab"; cmd.CommandTimeout = 5;//命令超时时间

1. 首先在数据库中执行以下sql脚本。使用显式事务,但不关闭事务

begin tran    update [dbo].[TestTab] set value = 0 where name = 'kk'--  rollback tran

2.  VS 中执行代码


结果错误如下:

CommandTimeout: 5System.Data.sqlClIEnt.sqlException (0x80131904): Timeout 时间已到。在 *** 作完成之前超时时间已过或服务器未响应。 ---> System.ComponentModel.Win32Exception (0x80004005): 等待的 *** 作过时。   在 System.Data.sqlClIEnt.sqlConnection.OnError(sqlException exception,String method)   在 System.Data.sqlClIEnt.sqlCommand.ExecuteReader()   在 dbConnectionTest.Program.Main(String[] args) 位置 e:\Tempfile\SSIS\ConnectPoolTest\ConnectPoolTest\Program.cs:行号 20ClIEntConnectionID:6b476a0d-4fc1-4f99-8208-0d61d268d4e7


【后台 kill 该连接】

上面的代码改以下两部分:超时设置30秒,执行SQL语句20秒,主要是有时间在数据库中查询并kill 掉该链接。

string sqlstring = "waitfor delay '00:00:20';SELECT [name],[value] FROM dbo.TestTab"; cmd.CommandTimeout = 30;//命令超时时间


1. 首先在VS执行代码

2. 在数据库中查找该连接并kill掉

select p.spID,p.lastwaittype,p.cmd,p.loginame,p.program_name,s.textfrom master.dbo.sysprocesses p cross apply sys.dm_exec_sql_text(p.sql_handle) swhere spID >50 and s.text like '%waitfor delay%' and spID<>@@SPIDkill 66



结果错误如下:

CommandTimeout: 30System.Data.sqlClIEnt.sqlException (0x80131904): 当前命令发生了严重错误。应放弃任何可能产生的结果。当前命令发生了严重错误。应放弃任何可能产生的结果。   在 System.Data.sqlClIEnt.sqlConnection.OnError(sqlException exception,String method)   在 System.Data.sqlClIEnt.sqlCommand.ExecuteReader()   在 dbConnectionTest.Program.Main(String[] args) 位置 e:\Tempfile\SSIS\ConnectPoolTest\ConnectPoolTest\Program.cs:行号 20ClIEntConnectionID:ec8021d9-4fbb-4994-8e7b-1a4b95fcb1f2



【网络延迟或丢包】

1. 首先打开sqlServer 配置管理器,因本地测试,所以把 shared memory 、named pipes 禁用,只允许通过 TCP/IP 访问 sqlServer。

2.  下载 打开 clumsy ,对端口 1433 启用 延迟 或丢包!(更多参考 : Clumsy logo差网络环境模拟工具 Clumsy)


3. 执行以下脚本

using System;using System.Data.sqlClIEnt;namespace dbConnectionTest{    class Program    {        static voID Main(string[] args)        {            string connstring = @"Data source=1card1-hzc;Integrated Security=sspI;Initial Catalog=DemoDB";            string sqlstring = "SELECT [name],[value] FROM dbo.TestTab;";            using (sqlConnection conn = new sqlConnection(connstring))            {                try                {                    sqlCommand cmd = new sqlCommand(sqlstring,conn);                    cmd.CommandTimeout = 30;//命令超时时间                    Console.Writeline("CommandTimeout: {0}",r[1].ToString());                }                catch (sqlException se)                {                    Console.Writeline(se);                }                finally                {                    conn.Close();                }                Console.Readline();            }        }    }}


结果错误如下:

CommandTimeout: 30System.Data.sqlClIEnt.sqlException (0x80131904): 连接超时时间已到。在尝试使用预登录握手确认时超过了此超时时间。这可能是因为预登录握手失败或服务器未能及时响应。  尝试连接到此服务器时花费的持续时间是 - [Pre-Login] initialization=54072;handshake=25; ---> System.ComponentModel.Win32Exception (0x80004005): 等待的 *** 作过时。   在 System.Data.sqlClIEnt.sqlInternalConnection.OnError(sqlException exception,Boolean asyncclose)   在 System.Data.sqlClIEnt.TdsParserStateObject.ReadSnIError(TdsParserStateObject stateObj,UInt32 error)   在 System.Data.sqlClIEnt.TdsParserStateObject.ReadSnisyncOverAsync()   在 System.Data.sqlClIEnt.TdsParserStateObject.TryReadNetworkPacket()   在 System.Data.sqlClIEnt.TdsParser.ConsumePreLoginHandshake(Boolean encrypt,Boolean trustServerCert,Boolean integratedSecurity,Boolean& marsCapable)   在 System.Data.sqlClIEnt.TdsParser.Connect(ServerInfo serverInfo,sqlInternalConnectionTds connHandler,Boolean ignoreSniOpenTimeout,Int64 timerExpire,Boolean encrypt,Boolean withFailover)   在 System.Data.sqlClIEnt.sqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo,String newPassword,securestring newSecurePassword,TimeoutTimer timeout,Boolean withFailover)   在 System.Data.sqlClIEnt.sqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo,Boolean redirectedUserInstance,sqlConnectionString connectionoptions,sqlCredential credential,TimeoutTimer timeout)   在 System.Data.sqlClIEnt.sqlInternalConnectionTds.OpenLoginEnList(TimeoutTimer timeout,Boolean redirectedUserInstance)   在 System.Data.sqlClIEnt.sqlInternalConnectionTds..ctor(DbConnectionPoolIDentity IDentity,Object provIDerInfo,BooleanredirectedUserInstance,sqlConnectionString userConnectionoptions,SessionData reconnectSessionData)   在 System.Data.sqlClIEnt.sqlConnectionFactory.CreateConnection(DbConnectionoptions options,DbConnectionPoolKey poolKey,Object poolGroupProvIDerInfo,DbConnectionPool pool,DbConnection owningConnection,DbConnectionoptions userOptions)   在 System.Data.ProvIDerBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool,DbConnection owningObject,DbConnectionoptions options,DbConnectionoptions userOptions)   在 System.Data.ProvIDerBase.DbConnectionPool.CreateObject(DbConnection owningObject,DbConnectionoptions userOptions,DbConnectionInternal oldConnection)   在 System.Data.ProvIDerBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject,DbConnectionInternal oldConnection)   在 System.Data.ProvIDerBase.DbConnectionPool.TryGetConnection(DbConnection owningObject,UInt32 waitForMultipleObjectsTimeout,Boolean allowCreate,Boolean onlyOneCheckConnection,DbConnectionInternal& connection)   在 System.Data.ProvIDerBase.DbConnectionPool.TryGetConnection(DbConnection owningObject,taskcompletionsource`1 retry,DbConnectionInternal& connection)   在 System.Data.ProvIDerBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection,DbConnectionInternal oldConnection,DbConnectionInternal& connection)   在 System.Data.ProvIDerBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection,DbConnectionFactory connectionFactory,DbConnectionoptions userOptions)   在 System.Data.ProvIDerBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection,DbConnectionoptions userOptions)   在 System.Data.sqlClIEnt.sqlConnection.TryOpenInner(taskcompletionsource`1 retry)   在 System.Data.sqlClIEnt.sqlConnection.TryOpen(taskcompletionsource`1 retry)   在 System.Data.sqlClIEnt.sqlConnection.open()   在 dbConnectionTest.Program.Main(String[] args) 位置 e:\Tempfile\SSIS\ConnectPoolTest\ConnectPoolTest\Program.cs:行号 19


【死锁】

1. 先启用回 shared memory 、named pipes ,执行以下代码,sql脚本中设置等待10秒钟。

using System;using System.Data.sqlClIEnt;namespace dbConnectionTest{    class Program    {        static voID Main(string[] args)        {            string connstring = @"Data source=1card1-hzc;Integrated Security=sspI;Initial Catalog=DemoDB";            string sqlstring = "update dbo.TestTab set value=0;WAITFOR DELAY '00:00:10';update dbo.TestTab2 set value=0;";             using (sqlConnection conn = new sqlConnection(connstring))            {                conn.open();                sqlCommand cmd = conn.CreateCommand();                sqlTransaction trans = conn.BeginTransaction();                try                {                    cmd.Connection = conn;                    cmd.Transaction = trans;                    cmd.CommandText = sqlstring;                    cmd.ExecuteNonquery();                    trans.Commit();                }                catch (sqlException se)                {                    trans.Rollback();                    Console.Writeline(se);                }                finally                {                    conn.Close();                }                Console.Readline();            }        }    }}

2. 紧接着在数据库中执行以下脚本,使事务交叉。

BEGIN TRAN    UPDATE dbo.TestTab2 SET value=1;    UPDATE dbo.TestTab SET value=1;COMMIT TRAN

结果错误如下:(有时死锁是发生在 第二步,执行多几次使发生在第一步的代码中)

System.Data.sqlClIEnt.sqlException (0x80131904): 事务(进程 ID 68)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。   在 System.Data.sqlClIEnt.sqlConnection.OnError(sqlException exception,Boolean& dataReady)   在 System.Data.sqlClIEnt.sqlCommand.RunExecuteNonqueryTds(String methodname,Boolean asyncWrite)   在 System.Data.sqlClIEnt.sqlCommand.InternalExecuteNonquery(taskcompletionsource`1 completion,String methodname,Boolean sendtopipe,Boolean asyncWrite)   在 System.Data.sqlClIEnt.sqlCommand.ExecuteNonquery()   在 dbConnectionTest.Program.Main(String[] args) 位置 e:\Tempfile\SSIS\ConnectPoolTest\ConnectPoolTest\Program.cs:行号 22


参考:

SqlConnection.BeginTransaction 方法 (IsolationLevel)

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

《易车网连接超时研究

总结

以上是内存溢出为你收集整理的SQLServer 超时测试研究全部内容,希望文章能够帮你解决SQLServer 超时测试研究所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1168585.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存