接触过 ORACLE 的用户一定对“自治事务”不会陌生,那么在 SQL Server 中如何实现这个功能?请看下面。何为自治事务?简单的说,就是让内部的事务可以独立的提交和回滚,不受外部事务的影响。要具体了解,请看我的 BLOG。DLL 文件/*
* csc.exe /r:c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Transactions.dll /target:library AutoTranClass.cs
*/
using System;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Transactions; public class AutoTran
{
[SqlProcedure]
public static void ExecuteATStmt(SqlString sql, SqlString dbname, SqlInt16 iso)
{
// 创建不加入环境事务的事务作用域
using (TransactionScope trans = new TransactionScope(TransactionScopeOption.Suppress))
{
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
conn.Open(); // 获取过程调用者的安全上下文
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "select suser_name()";
string loginame = (string)cmd.ExecuteScalar(); // 创建 LOOPBACK 连接(禁止使用连接池)
using (SqlConnection connAT =
new SqlConnection("server=.;integrated security=true;database=master;pooling=false"))
{
connAT.Open();
connAT.ChangeDatabase((string)dbname); SqlCommand cmdAT = connAT.CreateCommand(); // 定义自治事务的事务隔离等级
string level;
switch ((Int16)iso)
{
case 1:
level = "read uncommitted";
break;
case 3:
level = "repeatable read";
break;
case 4:
level = "serializable";
break;
case 5:
level = "snapshot";
break;
default:
level = "read committed";
break;
}
cmdAT.CommandText = "set transaction isolation level " + level;
cmdAT.ExecuteNonQuery(); // 将 CLR 存储过程运行的安全上下文切换到调用者的,
//从而避免 CLR 过程运行在 SQL Server 服务进程的安全上下文中
cmdAT.CommandText = "execute as login = '" + loginame + "' with no revert";
cmdAT.ExecuteNonQuery(); // 执行 SQL 语句
cmdAT.CommandText = (string)sql;
cmdAT.ExecuteNonQuery();
}
}
trans.Complete();
}
}
}
CLR 过程use master
goexec sp_configure 'show advanced options',1;
go
reconfigure
go
exec sp_configure 'clr enabled',1;
go
reconfigure
goalter database master set trustworthy on;
goif object_id('dbo.ExecuteATStmt') is not null
drop procedure dbo.ExecuteATStmt;
goif exists (select * from sys.assemblies where name='AutoTran')
drop assembly AutoTran;
go
create assembly AutoTran authorization dbo
from 'C:\Devs\Projects\clrAutoTran\clrAutoTran\bin\Release\clrAutoTran.dll'
with permission_set=external_access;
gocreate procedure dbo.ExecuteATStmt
@stmt nvarchar(max), @dbname nvarchar(128)='master', @iso smallint=2
as external name AutoTran.AutoTran.ExecuteATStmt;
还有演示代码(在我的 BLOG 上啦)其实,CLR 是非常好的功能,可以弥补 T-SQL 的很多不足;编写也非常简单,只要会 .net 编成就可以了。希望可以抛砖引玉。
* csc.exe /r:c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Transactions.dll /target:library AutoTranClass.cs
*/
using System;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Transactions; public class AutoTran
{
[SqlProcedure]
public static void ExecuteATStmt(SqlString sql, SqlString dbname, SqlInt16 iso)
{
// 创建不加入环境事务的事务作用域
using (TransactionScope trans = new TransactionScope(TransactionScopeOption.Suppress))
{
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
conn.Open(); // 获取过程调用者的安全上下文
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "select suser_name()";
string loginame = (string)cmd.ExecuteScalar(); // 创建 LOOPBACK 连接(禁止使用连接池)
using (SqlConnection connAT =
new SqlConnection("server=.;integrated security=true;database=master;pooling=false"))
{
connAT.Open();
connAT.ChangeDatabase((string)dbname); SqlCommand cmdAT = connAT.CreateCommand(); // 定义自治事务的事务隔离等级
string level;
switch ((Int16)iso)
{
case 1:
level = "read uncommitted";
break;
case 3:
level = "repeatable read";
break;
case 4:
level = "serializable";
break;
case 5:
level = "snapshot";
break;
default:
level = "read committed";
break;
}
cmdAT.CommandText = "set transaction isolation level " + level;
cmdAT.ExecuteNonQuery(); // 将 CLR 存储过程运行的安全上下文切换到调用者的,
//从而避免 CLR 过程运行在 SQL Server 服务进程的安全上下文中
cmdAT.CommandText = "execute as login = '" + loginame + "' with no revert";
cmdAT.ExecuteNonQuery(); // 执行 SQL 语句
cmdAT.CommandText = (string)sql;
cmdAT.ExecuteNonQuery();
}
}
trans.Complete();
}
}
}
CLR 过程use master
goexec sp_configure 'show advanced options',1;
go
reconfigure
go
exec sp_configure 'clr enabled',1;
go
reconfigure
goalter database master set trustworthy on;
goif object_id('dbo.ExecuteATStmt') is not null
drop procedure dbo.ExecuteATStmt;
goif exists (select * from sys.assemblies where name='AutoTran')
drop assembly AutoTran;
go
create assembly AutoTran authorization dbo
from 'C:\Devs\Projects\clrAutoTran\clrAutoTran\bin\Release\clrAutoTran.dll'
with permission_set=external_access;
gocreate procedure dbo.ExecuteATStmt
@stmt nvarchar(max), @dbname nvarchar(128)='master', @iso smallint=2
as external name AutoTran.AutoTran.ExecuteATStmt;
还有演示代码(在我的 BLOG 上啦)其实,CLR 是非常好的功能,可以弥补 T-SQL 的很多不足;编写也非常简单,只要会 .net 编成就可以了。希望可以抛砖引玉。
一样的回滚了。
具体时间是从20号开始 ! 如果大家在使用电脑的时候,系统提示你所使用的微软产品是盗版软件等等,而且还会在右下角出现蓝色的小星星~~这是因为:由于美国最近要针对中国上诉WTO知识产权保护问题,微软正在为美国政府搜集相关证据,在最近自动更新中包含检测盗版副本程序。为了咱中国利益,从20号开始,请大家不要开启自动更新。
如果起诉成功,中国将要赔款几百亿。已经开启,当提示要你安装“正版增值计划”请别安装!安装后会在任务栏右下角出现一个蓝色五角星符号!!!这样就会被微软跟踪锁定,以向美国政府提供证据!
请大家转到其他群上顺带一个,大家转发,这个直接影响所有中国电脑用户的利益。
另外提醒大家:以后在中国去麦当劳,肯德基一定记得要发票!!!
麦当劳、肯德基每年在中国,因为我们不习惯要发票的原因,而掠走将近2亿的税收。 请把这条信息完好(不加任何修改复制)发至其它群体。 是中国人的就转发一下。累不了!