如何在不锁定其他事务的情况下写入表

时间:2016-10-05 08:48:35

标签: sql sql-server sql-server-2008-r2

我有一个中央记录表,记录了各种活动。 有一个用于写入日志的过程,如下所示:

create procedure [client].[procClient_LogText]
(
    @LogText nvarchar(4000),
    @LogLevel tinyint = 1,
    @LogLongText nvarchar(max) = NULL,
    @LogModule nvarchar(200) = NULL
)
as
insert into dbo.tblLog(LogLevel, LogText, LogLongText, LogModule) 
values (@LogLevel, @LogText, @LogLongText, @LogModule);

现在我有一个长的交易需要5-10分钟。在此期间,会记录一些步骤。问题是日志表被锁定。而其他进程会导致超时或速度变慢。

我想在协议中写入事务中的日志表,但写入日志本身不一定是事务的一部分。 因此,在回滚的情况下,日志应该仍然存在。

这可能吗?

2 个答案:

答案 0 :(得分:1)

如果您从应用程序服务器调用procedure,那么您可以使用insert语句而不是table命令进入日志select无论事务是提交还是回滚,都在事务之后重用。使用这些结果,您可以生成insert语句,将insert条记录到日志table中。

答案 1 :(得分:1)

Table variables aren't affected by user transaction rollback

因此,在复杂存储过程的开头创建一个表变量,其结构与永久tblLog表的结构相同。

将所有记录步骤插入此表变量而不是永久tblLog表。

在复杂存储过程结束时(无论是提交还是回滚主要工作),使用一个简单的tblLog将表变量中的所有行复制到永久INSERT表中。

因此,永久tblLog表的锁定将保持最小。

显然,如果主存储过程遇到严重错误,某些日志将会丢失,严重到足以在中间中止该过程并且永远不会到达从临时复制行的最终INSERT表变量进入永久tblLog表。