这个MSDN文章声明:
隔离级别具有连接范围,并且一旦为使用set事务隔离级别语句的连接设置,它将一直有效,直到连接关闭或设置另一个隔离级别为止。当连接关闭并返回到池时,将保留上次SET事务隔离级别语句中的隔离级别。重用池连接的后续连接使用连接池时有效的隔离级别。
SqlConnection类没有可能保持隔离级别的成员。那么连接如何知道要在哪个隔离级别上运行呢?
我之所以问这个问题,是因为有以下情况:
问题:
决议: 池连接返回可序列化隔离级别的原因如下:
希望能消除一些疑虑。:)
发布于 2010-09-21 11:54:49
隔离级别是在底层DBMS中实现的,比如SqlServer。设置隔离级别很可能设置SQL命令,这些命令设置连接的隔离级别。
只要连接保持打开,DBMS就会保持隔离级别。因为连接被放入池中,所以它保持打开,并保持以前的设置。
在处理隔离级别时,应该在任何事务结束时重置隔离级别,或者更好的是,在请求新连接时设置隔离级别。
发布于 2010-09-21 14:46:14
SqlConnection.BeginTransaction接受一个IsolationLevel参数,这就是控制SqlClient连接的隔离级别的方法。另一个选项是使用泛型System.Transactions,并在传递给TransactionScope 构造函数的TransactionOptions.IsolationLevel中指定隔离级别。在SqlClient和System.Transactions编程模型中,必须为每个事务显式指定隔离级别。如果未指定,则将使用默认设置( SqlClient已提交读,System.Transactions可序列化)。
池连接不是盲目重用的。它们有隐藏的内部成员来跟踪当前状态,如当前事务、挂起的结果等,并且框架可以清理返回到池的连接。仅仅因为在编程模型中没有公开状态,这并不意味着不存在(这适用于任何库类,任何类设计人员都可以将成员隐藏在internal保护伞下)。
最后,从池中重新使用的任何连接都会调用sp_reset_connection,这是一个服务器过程,用于清理服务器端会话的状态。
发布于 2011-11-14 20:41:36
它不将隔离级别返回到原始值。一个使用实体的示例需要一个空事务来重置级别(尽管它显然不需要提交(不需要.Complete() )。
使用DB服务器上的SP更改iso级别的尝试不起作用。输出:
以前: ReadCommitted 期间:可序列化 之后:可序列化 SP尝试重置后:可序列化 在由XACT: ReadCommitted复位时 XACT: ReadCommitted复位后
// 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 https://stackoverflow.com/questions/3759897
复制相似问题