相关疑难解决方法(0)

嵌套存储过程包含TRY CATCH ROLLBACK模式?

我对以下模式的副作用和潜在问题很感兴趣:

CREATE PROCEDURE [Name]
AS
BEGIN
    BEGIN TRANSACTION
    BEGIN TRY
        [...Perform work, call nested procedures...]
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION
        RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc]
    END CATCH
END
Run Code Online (Sandbox Code Playgroud)

据我所知,当使用单个过程时,此模式是合理的 - 过程将完成所有语句而不会出错,或者它将回滚所有操作并报告错误.

但是,当一个存储过程调用另一个存储过程来执行某个子工作单元时(理解为较小的过程有时会单独调用),我看到与回滚有关的问题 - 一条信息性消息(级别16)发表声明The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION..我假设是因为子过程中的回滚总是回滚最外层事务,而不仅仅是子过程中启动的事务.

我确实希望整个事情回滚并在发生任何错误时中止(并且错误报告给客户端作为SQL错误),我只是不确定外层试图回滚事务的所有副作用已经回滚过了.也许@@TRANCOUNT在每个TRY CATCH层进行回滚之前检查一下?

最后是客户端(Linq2SQL),它有自己的事务层:

try
{
    var context = new MyDataContext();
    using (var transaction = new TransactionScope())
    {       
            // Some Linq stuff
        context.SubmitChanges();
        context.MyStoredProcedure();
        transactionComplete();
    }
}
catch
{
    // An …
Run Code Online (Sandbox Code Playgroud)

stored-procedures transactions sql-server-2005 linq-to-sql

54
推荐指数
2
解决办法
3万
查看次数

连接关闭后,未提交的事务会发生什么?

它们会立即回滚吗?它们会在一段时间后回滚吗?他们是否处于未承诺状态?

如果使用连接池并且只是重置连接,行为是否相同?

sql sql-server transactions connection-pooling

43
推荐指数
3
解决办法
3万
查看次数

为什么SET XACT_ABORT不是默认行为?

在Dan Guzman的博客上阅读这篇文章,我想知道:为什么不是SET XACT_ABORT ON默认行为?是否有一个地方是有害的,或案件比不太理想/效率SET XACT_ABORT OFF

sql sql-server transactions sql-server-2005

18
推荐指数
1
解决办法
4061
查看次数

如果超时,查询会发生什么?

假设我有一个发送到我的SQL-Server数据库的查询,它需要超过30秒,并且我的程序抛出SQL Query Timeout异常.查询是否仍然在我的数据库上徘徊,或者一旦抛出异常就会终止它?

c# sql sql-server

12
推荐指数
1
解决办法
5205
查看次数

如何使SET XACT_ABORT ON回滚事务?

根据联机丛书文档SET XACT_ABORT ON,我得到的印象是,如果T-SQL语句引发运行时错误,整个事务将终止并回滚:

备注

当SET XACT_ABORT为ON时,如果Transact-SQL语句引发运行时错误,则终止并回滚整个事务.

在SQL Server 2008 R2中测试:

SET XACT_ABORT ON;
BEGIN TRANSACTION;
PRINT 'TranCount befor an error = '+CAST(@@Trancount AS varchar(50))

DROP TABLE QuertyAsdf

PRINT 'TranCount after an error = '+CAST(@@Trancount AS varchar(50))
Run Code Online (Sandbox Code Playgroud)

给出输出:

TranCount befor an error = 1
Msg 3701, Level 11, State 5, Line 6
Cannot drop the table 'QwertyAsdf', because it does not exist or you do not have permission.
TranCount after an error = 1
Run Code Online (Sandbox Code Playgroud)

SET XACT_ABORT ON如果出现错误 …

sql-server sql-server-2008-r2 xact-abort

7
推荐指数
1
解决办法
6390
查看次数

存储过程和SqlCommand超时

如果我使用SqlCommand运行存储过程并且SqlCommand超时,StoredProc会继续执行还是在SqlCommand断开连接时强行退出?

c# sql sql-server timeout sqlcommand

6
推荐指数
1
解决办法
2255
查看次数

当对象不存在时处理事务错误

我在MSDN Lbrary中发现和文章解释说try/catch不能处理无法找到对象时抛出的错误.所以,即使我在try/catch中包装一个事务,回滚短语也不会执行:

BEGIN TRY
BEGIN TRANSACTION

    SELECT 1 FROM dbo.TableDoesNotExists
    PRINT ' Should not see this'
    COMMIT TRANSACTION
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION
    SELECT
            ERROR_MESSAGE()
END CATCH

--PRINT 'Error Number before go: ' + CAST(@@Error AS VARCHAR)

go
PRINT 'Error Count After go: ' + CAST(@@Error AS VARCHAR)
PRINT 'Transaction Count ' + CAST(@@TRANCOUNT AS VARCHAR)
Run Code Online (Sandbox Code Playgroud)

当对象不存在时,特别是涉及事务时,建议的方法是处理抛出的错误.我应该用这一段代码代替最后两个打印语句:

IF @@ERROR <> 0 AND @@TRANCOUNT > 0
BEGIN   
    PRINT 'Rolling back txn'
    ROLLBACK TRANSACTION
END 

go

PRINT 'Transaction Count again: ' …
Run Code Online (Sandbox Code Playgroud)

sql transactions try-catch

6
推荐指数
1
解决办法
1396
查看次数

SQL Server SET XACT_ABORT ON 与 TRY...CATCH 存储过程内的块

我正在开发游戏数据库。我有一个存储过程,由游戏客户端在传送、登录、注销、死亡等过程中执行。游戏客户端是硬编码的,我无法编辑。

我正在我的程序中做一些事情,例如如果角色登录到游戏,然后将项目添加到角色的库存中。

对于每种不同类型的流程,我都有IF块,并且TRY...CATCH每个“IF”块中都有块,以便能够处理程序中的任何错误。

TRY...CATCH所以,我的问题是,以这种方式使用块确实有意义吗?或者我应该使用SET XACT_ABORT ON声明而不是TRY...CATCH?哪一个更好?顺便说一句,如果IF块中出现任何错误,则该块必须是完整的ROLLBACK

另外,我的程序是由游戏客户端高度执行的。有近 800 个在线角色一直在游戏中移动并执行我的程序。它应该尽可能快地执行。

ALTER PROCEDURE [dbo].[_AddLogChar]
    @CharID  INT,
    @EventID TINYINT,
    @Data1   INT,
    @Data2   INT,
    @strPos  VARCHAR(64),
    @Desc    VARCHAR(128)
AS
    ---- !!! KILL PROCEDURE !!! ----
    IF (@EventID NOT IN (4,6,20))
    BEGIN
        RETURN 0;
    END

    ---- BATTLE ARENA | ACADEMY ----
    IF (@EventID = 20)
    BEGIN
        BEGIN TRY
            BEGIN TRANSACTION TRAN_Battle_Arena

            -- Declaration of variables for battle area conditions
            DECLARE @CharInBattle VARCHAR(64) …
Run Code Online (Sandbox Code Playgroud)

t-sql sql-server stored-procedures

2
推荐指数
1
解决办法
3129
查看次数