SQL Server 自治事务(CLR 实现)

xman_78tom 2010-09-30 11:21:01
加精
接触过 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
go

exec sp_configure 'show advanced options',1;
go
reconfigure
go
exec sp_configure 'clr enabled',1;
go
reconfigure
go

alter database master set trustworthy on;
go

if object_id('dbo.ExecuteATStmt') is not null
drop procedure dbo.ExecuteATStmt;
go

if 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;
go

create procedure dbo.ExecuteATStmt
@stmt nvarchar(max), @dbname nvarchar(128)='master', @iso smallint=2
as external name AutoTran.AutoTran.ExecuteATStmt;


还有演示代码。。。(在我的 BLOG 上啦)

其实,CLR 是非常好的功能,可以弥补 T-SQL 的很多不足;编写也非常简单,只要会 .net 编成就可以了。希望可以抛砖引玉。

...全文
1656 159 打赏 收藏 转发到动态 举报
写回复
用AI写文章
159 条回复
切换为时间正序
请发表友善的回复…
发表回复
deicide930 2010-10-12
  • 打赏
  • 举报
回复
嗯嗯,学习
www_huabo 2010-10-12
  • 打赏
  • 举报
回复
学习 。。
jhuali520 2010-10-12
  • 打赏
  • 举报
回复
学习!
lfywy 2010-10-11
  • 打赏
  • 举报
回复
mark xia~~~~~~~~~~~~~~~
bao8693 2010-10-11
  • 打赏
  • 举报
回复
好好学习下
幻影时空 2010-10-11
  • 打赏
  • 举报
回复
不错,这个实用~ 支持一下!
boombacn 2010-10-11
  • 打赏
  • 举报
回复
我试试我的积分会不会因回贴而增加,在我发布这句话前是20分
Upupupupp 2010-10-11
  • 打赏
  • 举报
回复
学习,顺便问下,那个代码粘贴格式咋弄的?
Gump201072 2010-10-11
  • 打赏
  • 举报
回复
这个还真没接触过
wsy87217 2010-10-11
  • 打赏
  • 举报
回复
学习了!
maeryuan 2010-10-11
  • 打赏
  • 举报
回复
这个我都看不懂的呢
jason1319251 2010-10-11
  • 打赏
  • 举报
回复
的确很不错~~~学习了~~~~
霸王卸甲 2010-10-11
  • 打赏
  • 举报
回复
很好,学习了。
很好两个字竟然内容太短。。。。。
suki_jy 2010-10-11
  • 打赏
  • 举报
回复
学习学习!!!!!!!!!!!!!!!哈哈
yanluosha 2010-10-11
  • 打赏
  • 举报
回复
没用过,感觉不好。首先,这样的业务设计没有必要。其次,效率有待观察。
sanbudengyun 2010-10-11
  • 打赏
  • 举报
回复
好好看看
sanbudengyun 2010-10-11
  • 打赏
  • 举报
回复
恩 好 太好了
fannairu 2010-10-10
  • 打赏
  • 举报
回复
太牛了
keepm 2010-10-10
  • 打赏
  • 举报
回复
学习了
jy01751567 2010-10-10
  • 打赏
  • 举报
回复
学习!!
加载更多回复(92)

34,587

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧