SQL Server事务如何提交事务

SQL Server事务如何提交事务,sql,sql-server,sql-server-2005,Sql,Sql Server,Sql Server 2005,我有SQLServer2005存储过程。有人正在事务中调用我的存储过程。在我的存储过程中,我记录了一些信息(插入到表中)。当更高级别的事务回滚时,它将删除我的插入 我是否可以提交我的插入并防止更高级别的回滚删除我的插入 谢谢即使您启动了一个新事务,它也将嵌套在外部事务中。SQL Server保证回滚将导致未修改的数据库状态。因此,无法在中止的事务中插入行 if OBJECT_ID('logs') is not null drop table logs create table logs (id

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

我是否可以提交我的插入并防止更高级别的回滚删除我的插入


谢谢

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

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
这里有一个解决办法,这是一个小把戏。使用
rpc out=true
remote proc transaction promotion=false
创建链接服务器。链接的服务器可以指向与正在运行过程的服务器相同的服务器。然后,您可以在处使用
execte()来执行新事务中的某些内容

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
这将以日志表中的一行结束,即使事务已回滚

下面是创建此类链接服务器的示例代码:

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'

事务中的任何内容都将成为该事务的一部分。如果您不希望它成为该事务的一部分,则不要将其放在内部。

Oracle
中,您可以使用自治事务,但是,
sqlserver
不支持它们

可以声明一个表变量并从存储过程返回它


表变量在
回滚后仍然有效
,但是,应修改上层代码以读取变量并永久存储其数据。

根据权限,您可以使用xp\u cmdshell调用OSQL,从而创建完全独立的连接。您也许可以使用CLR做类似的事情,尽管我从未尝试过。然而,我强烈建议不要做这样的事


最好的办法是确定代码和调用代码的约定——两者之间支持哪种契约。您可以规定在另一个事务中永远不会调用代码(这可能不是一个好主意),也可以规定在发生错误时调用代码的责任。

调用存储过程正在启动事务。所以我无法避免成为这笔交易的一部分。你能重新设计它的工作原理吗?这听起来像是一个糟糕的设计,大体上正是我想要的suggest@codingguy3000:找到了一个窍门,答案已编辑。这需要管理权限