当前位置: 首页 > 知识库问答 >
问题:

回滚事务请求没有相应的开始事务

居晗日
2023-03-14

我已经尝试将COMMIT TRAN放入如果否则循环中,但我仍然会收到这个错误。

我必须在班级中注册一名学生。如果注册后的席位数量为负数,我必须将其反转并打印一条消息说无法注册。我已经放置了其他错误消息,只是为了看看交易是如何工作的。

CREATE PROCEDURE dbo.EnrollStudent ( @CourseID  AS INTEGER,
                                     @StudentID AS VARCHAR(20) ) AS
BEGIN
   DECLARE @StatusID INTEGER
   DECLARE @Status VARCHAR(50)
   DECLARE @CurrentSeats INTEGER
   DECLARE @ErrorCode INTEGER
   SET @StatusID=0



      IF EXISTS (SELECT 1 
                    FROM dbo.CourseEnrollment 
                    WHERE dbo.CourseEnrollment.CourseId=@CourseID AND dbo.CourseEnrollment.StudentId=@StudentID )
        BEGIN

         BEGIN TRAN Tr1
         SET @StatusID = 1
         SELECT @ErrorCode=@@ERROR
         IF (@ErrorCode<>0) GOTO OTHERPROBLEM
         ELSE 
         COMMIT TRAN Tr1

        END


     IF EXISTS ( SELECT 1
                    FROM dbo.CourseEnrollment
                    FULL OUTER JOIN dbo.Courses
                    ON dbo.Courses.CourseId=@CourseID     
                    WHERE dbo.CourseEnrollment.StudentId<>@StudentID  AND dbo.Courses.Faculty IS NULL ) 
            BEGIN
            BEGIN TRAN Tr2
                SET @StatusID=2
                SELECT @ErrorCode=@@ERROR
                 IF (@ErrorCode<>0) GOTO OTHERPROBLEM2
                 ELSE
                 COMMIT TRAN Tr2

                 END



    IF @StatusID=0
    BEGIN
        IF EXISTS ( SELECT 1
                    FROM dbo.Courses    
                    WHERE dbo.Courses.CourseId=@CourseID AND dbo.Courses.Faculty IS NOT NULL )

                BEGIN


                BEGIN TRAN Tr3

                SET @StatusID=3


                BEGIN TRAN InsertingValues
                INSERT INTO dbo.CourseEnrollment (dbo.CourseEnrollment.StudentId,dbo.CourseEnrollment.CourseId)
                                                VALUES          (@StudentID,@CourseID);

                SELECT @ErrorCode=@@ERROR
                 IF (@ErrorCode<>0) GOTO InsertProblem
                 ELSE
                 COMMIT TRAN InsertingValues




                BEGIN TRAN UpdateCourses
                UPDATE dbo.Courses  
                    SET OpenSeats = OpenSeats-1 
                       WHERE dbo.Courses.CourseId = @CourseID

                SELECT @ErrorCode=@@ERROR
                 IF (@ErrorCode<>0) GOTO UpdateProblem
                 ELSE
                 COMMIT TRAN UpdateCourses




                SELECT @CurrentSeats=OpenSeats  
                    FROM dbo.Courses
                        WHERE dbo.Courses.CourseId = @CourseID

                        IF (@CurrentSeats<0) GOTO PROBLEM
                        ELSE
                        COMMIT TRAN Tr3


                END

    END



    OTHERPROBLEM:
         BEGIN
            PRINT 'Unable to set status'
            ROLLBACK TRAN
         END


    OTHERPROBLEM2:
                 BEGIN
                     PRINT 'Unable to set status'
                     ROLLBACK TRAN
                 END


     UpdateProblem:
                 BEGIN
                     PRINT 'Not able to update values'
                     ROLLBACK TRAN InsertingValues
                 END



    InsertProblem:
                 BEGIN
                     PRINT 'Not able to insert'
                     ROLLBACK TRAN InsertingValues
                 END



    PROBLEM:
                BEGIN
                    PRINT 'Seats Full!'
                    ROLLBACK TRAN
                END




     IF @StatusID = 1
        BEGIN  
         SET @Status = 'The Student is already enrolled'
        END;

     ELSE IF @StatusID = 2
         BEGIN 
            SET @Status = 'Cannot enroll until faculty is selected' 
         END

     ELSE IF @StatusID = 3
         BEGIN 
            SET @Status = 'Student Enrolled' 
        END

   SELECT @Status

END;

这正确地更新了表,但是给出了以下错误:

(1 row(s) affected)

(1 row(s) affected)
Unable to set status
Msg 3903, Level 16, State 1, Procedure EnrollStudent, Line 101
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
Unable to set status
Msg 3903, Level 16, State 1, Procedure EnrollStudent, Line 108
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
Not able to update values
Msg 3903, Level 16, State 1, Procedure EnrollStudent, Line 115
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
Not able to insert
Msg 3903, Level 16, State 1, Procedure EnrollStudent, Line 123
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.
Seats Full!
Msg 3903, Level 16, State 1, Procedure EnrollStudent, Line 131
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.

(1 row(s) affected)

共有3个答案

爱唯
2023-03-14

只是简单地看一下-这可能是因为您在启动事务时命名了事务(Tr1),但没有在错误处理程序中引用该名称吗?

冯亮
2023-03-14

如果事务名已命名,则需要指定要回滚的事务名。从这个开始。

之后,您可以告诉我们哪个事务失败了(确保之前没有提交该事务)。

BEGIN TRAN Tr1

-- your code 

ROLLBACK TRAN Tr1
谭毅然
2023-03-14

您收到的错误是因为您正在回滚而没有打开的事务(您已经提交或回滚)。考虑清理存储的proc的结构,尝试将整个存储的proc作为一个事务执行,然后在发生错误时回滚。您还可以通过检查事务是否打开来测试是否需要回滚:

BEGIN TRANSACTION;
BEGIN TRY

   --execute all your stored proc code here and then commit
   COMMIT;

END TRY
BEGIN CATCH

   --if an exception occurs execute your rollback, also test that you have had some successful transactions
   IF @@TRANCOUNT > 0 ROLLBACK;  

END CATCH
 类似资料:
  • 我正在处理一些旧的应用程序代码,其中似乎涉及到几个概念,因此我希望能够将它们改进为一个坚实而严格的实践。 基本上,整个代码都用这样的HibernateSessionRequest estFilter包装 然后,有一个拦截器,做这样的事情 然后还有更多的业务逻辑代码,包括更多的初始事务和会话清除等。 那么,问题是: 当在同一会话中多次调用beginTransaction时会发生什么 非常感谢。

  • 问题内容: 我正在运行一个简单的JUnit测试,又是一个应用程序DAO。问题是我总是得到: JUnit测试是: 如你所见,我明确声明不回滚此方法。 Spring JUnit支持是否总是将rollback设置为true? 问题答案: 它应该可以正常工作,就像你期望的那样,但是可能是你在被测类中打开了另一个事务,或者某个地方有其他功能/或错误。 顺便说一句,这个注释应该是足够的:

  • 问题内容: 我在EJB3无状态会话Bean中使用CMT。另外,我还创建了自己的具有注释“ @ApplicationException(rollback = true)”的异常。 要回滚事务时是否必须使用“ context.setRollbackOnly()”? 我可以通过在bean的public方法内抛出异常来回滚事务吗? 如果是这样(对Q#2的回答是“是”),我是否必须通过在方法中声明异常来将异

  • 情景故事时间: 我“继承”了一个程序,一个用于访问数据库的相当简单的webservice。该程序在某个地方有一个缺陷:它试图更新一个没有更新授权的表。该程序只具有更新数据库队列的权限(Oracle),以保存谁访问了什么信息。这是不受欢迎的行为,现在我纠正了它。注意:这与这个问题本身无关,它只是导致我提出这个问题的原因。 该程序使用Spring+Hibernate来管理和访问数据和事务。 因为程序的

  • 问题内容: 使用Spring(3.0.5),Hibernate(3.6.0)和Wicket(1.4.14)开发应用程序时遇到了一个奇怪的问题。问题是:我无法将任何对象保存或修改到数据库中。“不能”是指对象的所有更改或对EntityManager.persist(foo)的调用都被简单,无声地忽略。选择工作。 示例案例很简单-在某些检票页面上,我尝试将对象保存到数据库中,如下所示 这是comicDA

  • 我正在使用spring-test运行JUnit测试,我的代码如下所示 我的问题是我希望我的测试不影响其他测试。所以我想为每个测试创建一些类似回滚的东西。我为此找了很多,但到目前为止一无所获。我使用Hibernate和MySql来实现这个