首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL Server事务如何提交事务

问SQL Server事务如何提交事务
EN

Stack Overflow用户
提问于 2010-05-21 02:08:21
回答 4查看 772关注 0票数 2

我有SQL Server2005存储过程。有人正在事务中调用我的存储过程。在我的存储进程中,我记录了一些信息(插入到表中)。当更高级别的事务回滚时,它会删除我的insert。

有没有什么方法可以提交我的插入,并防止更高级别的回滚删除我的插入?

谢谢

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-05-21 02:10:12

即使您启动了一个新事务,它也会嵌套在外部事务中。SQL Server保证回滚将导致未修改的数据库状态。因此,您无法在中止的事务中插入行。

这里有一个绕过它的方法,这是一个小把戏。使用rpc out = true和remote proc transaction promotion = false创建链接服务器。链接服务器可以指向正在运行过程的同一服务器。然后,您可以使用execte (<query>) at <server>在新事务中执行某些操作。

代码语言:javascript
复制
if OBJECT_ID('logs') is not null drop table logs
create table logs (id int primary key identity, msg varchar(max))
if OBJECT_ID('TestSp') is not null drop procedure TestSp
go
create procedure TestSp as
execute ('insert into dbo.logs (msg) values (''test message'')') at LINKEDSERVER
go
begin transaction
exec TestSp
rollback transaction
select top 10 * from logs

这将以日志表中的一行结束,即使事务已回滚。

下面是创建这样一个链接服务器的示例代码:

代码语言:javascript
复制
IF  EXISTS (SELECT srv.name FROM sys.servers srv WHERE srv.server_id != 0 AND 
        srv.name = N'LINKEDSERVER')
    EXEC master.dbo.sp_dropserver @server=N'LINKEDSERVER', 
        @droplogins='droplogins'
EXEC master.dbo.sp_addlinkedserver @server = N'LINKEDSERVER', 
    @srvproduct=N'LOCALHOST', @provider=N'SQLNCLI', @datasrc=N'LOCALHOST', 
    @catalog=N'DatabaseName'
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVER', @optname=N'rpc out', 
     @optvalue=N'true'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'LINKEDSERVER', 
    @useself=N'True', @locallogin=NULL,@rmtuser=NULL, @rmtpassword=NULL
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVER', 
    @optname=N'remote proc transaction promotion', @optvalue=N'false'
票数 6
EN

Stack Overflow用户

发布于 2010-05-21 02:14:46

在Oracle中,您可以使用自主事务来实现这一点,但是,SQL Server不支持它们。

可以声明一个表变量,然后从存储过程中返回它。

表变量在ROLLBACK中仍然存在,但是,应该修改上层代码以读取变量并永久存储其数据。

票数 3
EN

Stack Overflow用户

发布于 2010-05-21 02:24:27

根据权限,您可以使用xp_cmdshell调用OSQL,从而创建一个完全独立的连接。你也许可以用CLR做一些类似的事情,尽管我从来没有尝试过。然而,I强烈建议不要做这样的事情。

最好的办法是确定您的代码和调用代码的约定是什么-这两者之间支持哪种类型的约定。您可以制定一个规则,即您的代码永远不会在另一个事务中调用(可能不是一个好主意),或者您可以对调用代码在发生错误时负责什么提出要求。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2876568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档