在MS SQL Server中,有一种方法可以检测数据库是否通过T-SQL命令设置了隔离级别 ALTER DATABASE <database> SET READ_COMMITTED_SNAPSHOT ON;
我无法在T-SQL或Management Studio的GUI中找到一种简单的方法来检测它.
TIA
这篇MSDN文章指出:
隔离级别具有连接范围范围,并且一旦设置为与SET TRANSACTION ISOLATION LEVEL语句的连接,它将保持有效,直到连接关闭或设置了另一个隔离级别.关闭连接并返回到池时,将保留最后一个SET TRANSACTION ISOLATION LEVEL语句的隔离级别.重新使用池连接的后续连接使用在连接池时生效的隔离级别.
该SqlConnection的类有任何成员可能持有的隔离级别.那么连接如何知道在哪个隔离级别运行?
我问这个的原因是因为以下情况:
问题:
解决方案:
池化连接返回可序列化隔离级别的原因是由于以下原因:
- 你有一个连接池(让我们说CP1)
- CP1可能有50个连接.
- 从CP1中选择一个连接C1并使用Serializable执行它.此连接现在已设置其隔离级别.无论您做什么,都不会重置(除非此连接用于执行不同隔离级别的代码).
- 执行查询后,C1(Serializable)返回CP1.
- 如果再次执行步骤1-4,则使用的连接可能是除C1之外的其他连接,假设为C2或C3.因此,它的隔离级别也将设置为Serializable.
- 因此,慢慢地,Serialzable在CP1中设置为多个连接.
- 当您执行未进行显式隔离级别设置的查询时,从CP1中选择的连接将决定隔离级别.例如,如果此类查询请求连接并且CP1使用C1(Serializable)执行此查询,则此查询将在Serializable模式下执行,即使您未明确设置它.
希望能够澄清一些疑惑.:)
通过网络从C#.Net应用程序运行相同的存储过程会随着每次后续执行而逐渐变慢.它似乎比前一次执行花费的时间长两倍(最大值;读取).执行时间逐渐变慢,直到2个场景中的1个发生,此时SPROC的第一次执行再次"快速".
SqlConnection在所有测试期间打开并保持打开状态,则SPROC会逐渐变慢,直到运行任何其他 SPROC 或查询.SqlConnection在每次执行时打开和关闭,SPROC会逐渐变慢,直到至少8分钟过去.只有少数存储过程才会发生这种情况.一个是SELECT2 的简单查询JOINs,(SPROC 1)另一个是大规模1600+线SPROC(SPROC 2).
对于SPROC 1,执行时间似乎永远不会超过60秒,对于SPROC 2,执行时间似乎不会超过67秒.SPROC 1最初执行时间不到一秒,SPROC 2最初需要7秒.
只有SqlConnection在应用程序中使用SPROC运行SPROC时,才会发生这种情况.一旦使用了2个单独的SqlConnection对象,它们的行为与上述相同,但是是独立的.多次运行SPROC SqlConnection1会逐渐变慢,但第一次运行相同的SPROC时SqlConnection2,它会"快速".当多次运行时,它也会变慢SqlConnection2.
如果应用程序在安装了SQL Server 2008 R2的同一台计算机上运行(运行Windows Server 2008),则不会发生这种情况.执行时间始终一致.
从Management Studio中运行存储过程也不会因每次执行而变慢; 它总是一致的.
清除执行计划缓存(在SQL Server中)对观察到的行为没有影响.
为了创建一个测试应用程序以轻松测试/重现它,需要花费相当多的时间来缩小最初在更大的应用程序中观察到的这个问题.
从我在这里读到的,有一个4到8分钟的超时(SqlConnection.Close()在代码中调用之后),此时它关闭了与数据源的数据库连接.这似乎与我上面提到的方案2一致.
这使我相信它与SqlConnection使用的(以及与数据源的底层数据库连接)有关,因为在我的情况下启用了连接池,但为什么我会观察到这种行为,以及如何解决它?
我们正在使用.Net 2.0 Framework,如果这有任何区别的话.
上面列出了许多细节,如果我需要澄清任何内容,请告诉我.
唯一存在任何相似之处的Stack …
我已在C#代码中将隔离级别设置为readcommitted,并且我正在调用存储过程,由于某种原因该过程正在超时。该存储过程没有任何set isolation level语句。
在SQL Server中,数据库级别的隔离级别是读取已提交的快照。
那么将使用哪个隔离级别?在SQL Server中定义的一个,还是在C#中定义的一个?
此代码用于执行软删除.它首先删除记录.如果删除成功,则回滚然后更新同一记录的标志列.如果该记录具有依赖性并且无法删除,则不执行任何操作.为了知道,行动发生了,我保留了Status变量.但是,无论如何,它总是会产生无效的结果.我哪里错了.
ALTER PROCEDURE SoftDelete
(
@TableName nvarchar(50), @ColName nvarchar(50),
@Id nvarchar(50)
)
AS
BEGIN
DECLARE @qryDel nvarchar(MAX),@qryUpd nvarchar(MAX),@Status int = null,
@Param nvarchar(MAX)
SET @Param = N'@TableName nvarchar(50), @ColName nvarchar(50),
@Id nvarchar(50)'
SET @qryDel = N'delete from @tablename where @colname=@id'
SET @qryUpd = N'update @tablename set deleted = 1 where @colname=@id'
BEGIN TRY
BEGIN TRANSACTION
EXECUTE sp_executesql @qryDel, @Param, @TableName, @ColName, @Id
ROLLBACK TRANSACTION
BEGIN TRANSACTION
EXECUTE sp_executesql @qryUpd, @Param, @TableName, @ColName, @Id
COMMIT TRANSACTION
SET @Status = 1
END …Run Code Online (Sandbox Code Playgroud)