当前事务无法提交,也无法支持写入日志文件的操作。回滚交易

时间:2013-09-27 14:42:54

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

我知道还有其他问题与我发布的确切标题有关,但每个问题都非常特定于他们引用的查询或程序。

我在这里为大学管理Blackboard Learn系统,并且可以直接访问数据库。简而言之,存在导致系统崩溃的存储过程。有时,当系统更改被提交时,错误会被抛入后端的日志中,识别称为bbgs_cc_setStmtStatus的存储过程并使用The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.错误输出

这是SP的代码,但是,我没有写它,因为它是Blackboard在填充并为应用程序创建表时安装的“设备”库存。

USE [BBLEARN]
GO
/****** Object:  StoredProcedure [dbo].[bbgs_cc_setStmtStatus]    Script Date: 09/27/2013 09:19:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE              [dbo].[bbgs_cc_setStmtStatus](
   @registryKey   nvarchar(255),
   @registryVal   nvarchar(255),
   @registryDesc  varchar(255),
   @overwrite     BIT
) 
AS
BEGIN
  DECLARE @message varchar(200);

  IF (0 < (SELECT count(*) FROM bbgs_cc_stmt_status WHERE registry_key = @registryKey) ) BEGIN
    IF( @overwrite=1 ) BEGIN
      UPDATE bbgs_cc_stmt_status SET
        registry_value = @registryVal,
        description    = @registryDesc,
        dtmodified     = getDate()
      WHERE registry_key = @registryKey;
    END
  END
  ELSE BEGIN
    INSERT INTO bbgs_cc_stmt_status
        (registry_key, registry_value, description) VALUES
        (@registryKey, @registryVal, @registryDesc);
  END

  SET @message = 'bbgs_cc_setStmtStatus: Saved registry key [' + @registryKey + '] as status [' + @registryVal + '].';
  EXEC dbo.bbgs_cc_log @message, 'INFORMATIONAL';

END

我不期待Blackboard特定的支持,但我想知道是否有任何我可以检查的SQL Server 2008,看看是否有系统设置导致这种情况。我确实打开了Blackboard的票,但还没有听到任何消息。

以下是我检查的一些内容:

tempdb系统数据库:

我让templog的初始大小为100MB,并且自动增长100MB,不受限制地查看是否会导致问题。它似乎没有帮助。我们的实际tempdb从4GB开始,每次需要时自动增长。 tempdb中可用空间是否为tempdb实际大小的95-985是正常的吗?例如,现在tempdb的大小为12388.00 MB,可用空间为12286.37MB。

此外,主BBLEARN表的日志文件已停止增长,因为它已达到其最大自动格式。我将其初始大小设置为3GB以增加其大小。

3 个答案:

答案 0 :(得分:1)

我看到一些可能阻止提交的潜在错误但却不知道更多关于结构的错误:

  1. 嵌套if中的update子句尝试更新必须唯一的列(或列集)。因为检查仅验证至少有一个项目存在但不限制该检查以确保只存在一个项目

    IF (0 < (SELECT ...) ) BEGIN
    

    VS

    IF (1 = (SELECT ...) ) BEGIN
    

    您可以将非唯一值插入必须唯一的行。检查以确保更新运行的属性没有约束(特别是查找主键,标识和唯一约束)。可能是这个问题:低但非零。

  2. 应用程序未将值传递给所有参数,导致@message字符串为空,从而导致日志记录方法在尝试添加空字符串时出错。请记住,在SQL中有任何事情+ null = null所以,虽然你可以将值插入并更新为null,但是你不能以你提供的代码的方式记录空值。相反,要考虑空值,您应该将消息变量的setter更改为以下内容:

    SET @message = 'bbgs_cc_setStmtStatus: Saved registry key [' + COALESCE(@registryKey, '') + '] as status [' + COALESCE(@registryVal,'') + '].';
    

    根据报告的错误,这很可能是你的问题,但是再次没有应用程序代码(这可能会阻止传递null参数),没有任何方法可以知道。

  3. 另外,我会注意到,而不是做

    IF (0 < (SELECT count(*) ...) ) BEGIN
    

    我会用

    IF (EXISTS (SELECT 1 ...) ) BEGIN
    

    因为它更有效率。您不必返回子查询的每一行,因为执行计划将首先运行FROM语句并查看存在的行而不必实际评估select,计算这些行,然后将其与0进行比较。 / p>

    从这些建议开始,如果您可以返回更多信息,我可以帮助您解决更多问题。

答案 1 :(得分:0)

也许您可以使用MERGE语句: http://msdn.microsoft.com/fr-fr/library/bb510625%28v=sql.100%29.aspx

我认为它会更有效率。

答案 2 :(得分:-3)

  1. 启动SSMS
  2. 导航到数据库名称
  3. 右键单击数据库名称,然后选择“属性”&gt;选项
  4. 改变&#34;延迟耐久性&#34;
  5. 点击确定