怎样的SqlConnection管理的IsolationLevel

2025-05-15 04:56:48
推荐回答(1个)
回答1:

这MSDN文章指出:
隔离级别具有连接性的
范围,一旦为连接设置
用SET TRANSACTION ISOLATION
LEVEL它仍然有效
直到连接被关闭或
另一个隔离级别设置。当
连接关闭,并返回到
池,从隔离级别
最后SET TRANSACTION ISOLATION LEVEL
被保留。随后
一个连接池
隔离级别
那是在生效的本
连接池。
SqlConnection类有一个可容纳隔离级别。那么,如何连接知道什么隔离级别中运行???
我问这个的原因是以下情形的:
我打开一
在TransactionScope的序列化
模式,说“T1”。
开为T1的连接。
T1结束/处置,连接
追溯到连接池。
呼吁其他查询
连接(从获得后
连接池)和该查询运行
在可序列化的模式!
问题:
如何汇集连接仍然
知道什么隔离级别是
关联呢???
如何将其恢复为其他
事务级???
分辨率:
为什么池连接正在返回的串行化隔离级别的原因是由于以下原因:
你有一个连接池(比方说CP1)
CP1可能有50个连接。
你从CP1选择一个连接C1和序列化执行它。这种连接有其隔离级别设置完毕。
不管你做什么 CodeGo.net,这不会被复位(除非该连接是
用于在不同的隔离级别执行代码)。
执行查询C1(序列化)后,可以追溯到CP1。
如果步骤1-4,再次执行,那么将可能会比其他的C1连接,比方说,C2或C3。所以,这也将
有其隔离级别设置为可序列化。
因此,慢慢地,Serialzable被设置为在CP1多个连接。
当您执行在没有明确的隔离级别设置正在做一个查询,从CP1挑连接将决定
隔离级别。对于如如果这样的查询请求的连接
和CP1用C1(序列化)来执行该查询,然后这个查询
在串行化模式,即使你没有明确地将执行
设置它。
希望清除的几个疑点。 :)
本文地址 :CodeGo.net/199351/

-------------------------------------------------------------------------------------------------------------------------
1. 隔离级别是基础DBMS,说SqlServer的。设置隔离级别最有可能设置里面设置的隔离级别连接。
数据库管理系统保持隔离级别,只要连接保持打开状态。连接被放入池中,它保持打开状态,并保持之前的设定。
带隔离左右的水平,您应该重新设定隔离级别在任何交易结束时,或者甚至更好 CodeGo.net,将其设置在请求一个新的连接。
2.
SqlConnection.BeginTransaction接受一个IsolationLevel这是如何控制的SqlClient连接的隔离级别。另一种选择是通用的System.Transactions并指定隔离级别TransactionOptions.IsolationLevel传
递给在TransactionScope的构造函数。无论是在的SqlClient和System.Transactions的编程模型的隔离级别,必须
显式地为每个事务中指定。如果没有指定,则默认会(读已提交的的SqlClient,序列化的System.Transactions的)。

池连接不盲目,他们已经隐藏轨迹像当前事务的当前状态,等待结果等,并在可以清理一个连接返回到池中。只是状态是不是在编程模型暴露,这不是“不存在(这
适用于任何库类,任何类的设计者可以下internal伞)。
最后从池中的任何方面,它调用sp_reset_connection这是清理在服务器端的会话状态的服务器。
3.
它不隔离级别返回到原来的值.a个实体需要一个空的事务重置水平(虽然它apparentently不需要(否定的。完成()需要的话)。
试图改变这个iso数据库服务器上的SP不起作用。输出:
前:提交读取
期间:序列化
后:序列化
复位由SP尝试后:序列化
复位时通过XACT:提交读取
复位由XACT后:提交读取

// using Dbg = System.Diagnostics.Debug;
XactIso.iso isoEntity = new XactIso.iso();
using (isoEntity)
{
Dbg.WriteLine("Before: " + isoEntity.usp_GetXactIsoLevel().SingleOrDefault());
var xactOpts = new TransactionOptions();
xactOpts.IsolationLevel = System.Transactions.IsolationLevel.Serializable;
using (TransactionScope xact = new TransactionScope(TransactionScopeOption.Required, xactOpts))
{
Dbg.WriteLine("During: " + isoEntity.usp_GetXactIsoLevel().SingleOrDefault());
xact.Complete();
}
Dbg.WriteLine("After: " + isoEntity.usp_GetXactIsoLevel().SingleOrDefault());
isoEntity.usp_SetXactIsoLevel("ReadCommitted");
Dbg.WriteLine("After Reset by SP Attempt: " + isoEntity.usp_GetXactIsoLevel().SingleOrDefault());
// failed
var xactOpts2 = new TransactionOptions();
xactOpts2.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
using (TransactionScope xact2 = new TransactionScope(TransactionScopeOption.Required, xactOpts2))
Dbg.WriteLine("During Reset by XACT: " + isoEntity.usp_GetXactIsoLevel().SingleOrDefault());
// works w/o commit
Dbg.WriteLine("After Reset by XACT: " + isoEntity.usp_GetXactIsoLevel().SingleOrDefault());
}

其中来自链接
proc [Common].[usp_GetXactIsoLevel]
as
begin
select
case transaction_isolation_level
WHEN 0 THEN 'Unspecified'
WHEN 1 THEN 'ReadUncommitted'
WHEN 2 THEN 'ReadCommitted'
WHEN 3 THEN 'RepeatableRead'
WHEN 4 THEN 'Serializable'
WHEN 5 THEN 'Snapshot'
end as lvl
from sys.dm_exec_sessions
where session_id = @@SPID;
end

及(没有工作):
proc [Common].[usp_SetXactIsoLevel]
@pNewLevel varchar(30)
as
begin
if @pNewLevel = 'ReadUncommitted'
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
else if @pNewLevel = 'ReadCommitted'
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
else if @pNewLevel = 'RepeatableRead'
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
else if @pNewLevel = 'Serializable'
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
else if @pNewLevel = 'Snapshot'
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
else
raiserror('Unrecognized Transaction Isolation Level', 16, 1);
end