4

I know that there are other questions with the exact title as the one I posted but each of them are very specific to the query or procedure they are referencing.

I manage a Blackboard Learn system here for a college and have direct database access. In short there is a stored procedure that is causing system headaches. Sometimes when changes to the system get committed errors are thrown into logs in the back end, identifying a stored procedure known as bbgs_cc_setStmtStatus and erroring out with The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.

Here is the code for the SP, however, I did not write it, as it is a stock piece of "equipment" installed by Blackboard when it populates and creates the tables for the application.

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

I'm not expecting Blackboard specific support, but I want to know if there is anything I can check as far as SQL Server 2008 is concerned to see if there is a system setting causing this. I do have a ticket open with Blackboard but have not heard anything yet.

Here are some things I have checked:

tempdb system database:

I made the templog have an initial size of 100MB and have it auto grow by 100MB, unrestricted to see if this was causing the issue. It didn't seem to help. Our actual tempdb starts at 4GB and auto grows by a gig each time it needs it. Is it normal for the space available in the tempdb to be 95-985 of the actual size of the tempdb? For example, right now tempdb has a size of 12388.00 MB and the space available is 12286.37MB.

Also, the log file for the main BBLEARN table had stopped growing because it reached its maximum auto grwoth. I set its initial size to 3GB to increase its size.

4

3 回答 3

1

我看到了一些可能阻止提交但不了解更多结构的潜在错误,这些只是猜测:

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

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

    对比

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

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

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

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

    根据报告的错误,这更有可能是您的问题,但同样,如果没有应用程序代码(这可能会阻止传递空参数),则无法知道。

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

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

我会用

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

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

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

于 2013-09-27T23:08:42.437 回答
0

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

我认为它会更有效率。

于 2013-09-27T22:38:25.983 回答
-4
  1. 启动 SSMS
  2. 导航到数据库名称
  3. 右键单击数据库名称并选择“属性”>“选项”
  4. 将“延迟的耐久性”更改为允许
  5. 点击确定
于 2015-02-13T22:05:04.220 回答