【问题标题】:Concurrency Exception并发异常
【发布时间】:2018-12-11 18:09:27
【问题描述】:

我是唯一使用该系统的用户,此代码引发并发异常,我要做的就是更新状态并添加正在采用该任务的用户

OptimisticConcurrencyException:存储更新、插入或删除语句影响了意外数量的行 (0)。自加载实体后,实体可能已被修改或删除。有关理解和处理乐观并发异常的信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=472540

     namespace GoldMine.View.Notification.Home.Process {
   using PageInstruction = GraphiteGTC.Core.View.Element.Model.PageInstruction;
    using Notification = GoldMine.Model.Notification;
    using User = GoldMine.Model.User;
    using NotificationApprovalStatus = GoldMine.Model.NotificationApprovalStatus;
    using ButtonTypeOption = GoldMine.Model.ButtonTypeOption;

    /// <summary>
    ///
    /// Class housing the logic for OnClickAdoptApproveTaskButtonProcess
    ///
    /// </summary>
    public class OnClickAdoptApproveTaskButtonProcess : GoldMineViewProcess {
        /// <summary>
        ///
        /// View process inputs
        ///
        /// </summary>
        public new OnClickAdoptApproveTaskButtonProcessInputs Inputs {
            get { return ( OnClickAdoptApproveTaskButtonProcessInputs )base.Inputs; }
            set { base.Inputs = value; }
        }

        /// <summary>
        ///
        /// View process outputs
        ///
        /// </summary>
        public new OnClickAdoptApproveTaskButtonProcessOutputs Outputs {
            get { return ( OnClickAdoptApproveTaskButtonProcessOutputs )base.Outputs; }
            set { base.Outputs = value; }
        }

        /// <summary>
        ///
        /// UI outputs
        ///
        /// </summary>
        public OnClickAdoptApproveTaskButtonProcessUiOutputs UiOutputs {
            get { return new OnClickAdoptApproveTaskButtonProcessUiOutputs( Outputs ); }
        }

        /// <summary>
        ///
        /// Default parameter-less constructor
        ///
        /// </summary>
        public OnClickAdoptApproveTaskButtonProcess() {
            Name = "GoldMine.View.Notification.Home.Process.OnClickAdoptApproveTaskButtonProcess";
            Inputs = new OnClickAdoptApproveTaskButtonProcessInputs();
            Outputs = new OnClickAdoptApproveTaskButtonProcessOutputs();
            base.Outputs = Outputs;
            base.Inputs = Inputs;
            DelayedPropertyAssignments = new List<DelayedPropertyAssignment>();
        }

        /// <summary>
        ///
        /// Entry point for event processing
        ///
        /// </summary>
        protected override GraphiteGTCProcess ExecuteProcess( GTCEventRegistration executingEventRegistration ) {
            return base.ExecuteProcess( Inputs.EventRegistration );
        }

        /// <summary>
        ///
        /// Entry point for Business Logic Processing
        ///
        /// </summary>
        protected override GraphiteGTCProcess ExecuteForwardProcessing() {
            try {
                Outputs = new OnClickAdoptApproveTaskButtonProcessOutputs();

                Outputs.SessionToken = UiStringConverter.CreateSessionToken( Inputs.CurrentUser );
                Debugging.DebugWorker.Current.BeginProcess();
                Debugging.DebugWorker.Current.SetVariableValue( "ButtonType", Inputs.ButtonType );
                Debugging.DebugWorker.Current.SetVariableValue( "CurrentNotification", Inputs.CurrentNotification );
                Debugging.DebugWorker.Current.SetVariableValue( "PageInstructions", Outputs.PageInstructions );
                Debugging.DebugWorker.Current.SetVariableValue( "CurrentUser", Inputs.CurrentUser );
                Debugging.DebugWorker.Current.BeginInstruction( "b60bbb93-3a06-4a57-ace3-6024f91c94a0", "092c84bf-423e-454b-8efa-00749bc691ef" );

                // ShapeComment:[Create List of Page Instructions][b60bbb93-3a06-4a57-ace3-6024f91c94a0][4bf395e3-e0a1-4304-b987-dcdae594a524]
                Debugging.DebugWorker.Current.BeginInstruction( "b60bbb93-3a06-4a57-ace3-6024f91c94a0", "4bf395e3-e0a1-4304-b987-dcdae594a524" );
                Outputs.PageInstructions = new List<PageInstruction>();
                Debugging.DebugWorker.Current.SetVariableValue( "PageInstructions", Outputs.PageInstructions );

                // ShapeComment:[Get Receiver][b60bbb93-3a06-4a57-ace3-6024f91c94a0][6b9c89cc-79c7-4957-8164-9a0c25da7652]
                Debugging.DebugWorker.Current.BeginInstruction( "b60bbb93-3a06-4a57-ace3-6024f91c94a0", "6b9c89cc-79c7-4957-8164-9a0c25da7652" );
                #region Execute FindReceiverFromNotification Process

                var notificationFindReceiverFromNotificationProcess = new Notification( true ).FindReceiverFromNotificationProcess;
                notificationFindReceiverFromNotificationProcess.Inputs.EventRegistration = Inputs.EventRegistration;
                notificationFindReceiverFromNotificationProcess.Inputs.CurreuntUser = Inputs.CurrentUser;
                notificationFindReceiverFromNotificationProcess.Inputs.Notification = Inputs.CurrentNotification;
                notificationFindReceiverFromNotificationProcess.OverriddenValidations = OverriddenValidations;
                try {
                    notificationFindReceiverFromNotificationProcess.StartProcessing();
                    Outputs.Validations.AddRange( notificationFindReceiverFromNotificationProcess.Outputs.Validations );
                }
                catch ( ValidationResultException validationResultException ) {
                    Outputs.Validations.AddRange( validationResultException.Validations );
                    if ( validationResultException.ContainsError() ) {
                        throw new ValidationResultException( string.Format( "Processing {0} resulted in an error", Name ), Outputs.Validations );
                    }
                }

                #endregion
                var NotificationFindReceiverFromNotificationResult = notificationFindReceiverFromNotificationProcess;
                Debugging.DebugWorker.Current.SetVariableValue( "NotificationFindReceiverFromNotificationResult", NotificationFindReceiverFromNotificationResult );

                // ShapeComment:[Assign Notification as Read][b60bbb93-3a06-4a57-ace3-6024f91c94a0][324e353c-cdd6-488e-8c9c-3420051a06f5]
                Debugging.DebugWorker.Current.BeginInstruction( "b60bbb93-3a06-4a57-ace3-6024f91c94a0", "324e353c-cdd6-488e-8c9c-3420051a06f5" );
                Inputs.CurrentNotification.AdoptedBy = Inputs.CurrentUser;
                Inputs.CurrentNotification.ApprovalStatus = NotificationApprovalStatus.Approved;

                // ShapeComment:[Save Notification][b60bbb93-3a06-4a57-ace3-6024f91c94a0][c407dd77-b074-4c26-ac9b-557d73fec312]
                Debugging.DebugWorker.Current.BeginInstruction( "b60bbb93-3a06-4a57-ace3-6024f91c94a0", "c407dd77-b074-4c26-ac9b-557d73fec312" );
                GoldMine.View.Notification.Home.Process.SaveNotificationProcess SaveNotificationProcessResult = null;
                try {
                    SaveNotificationProcessResult = ( GoldMine.View.Notification.Home.Process.SaveNotificationProcess ) EventProcess.ExecuteUnregisteredViewEvent( "GoldMine.View.Notification.Home.Process.SaveNotificationProcess", Inputs.CurrentUser, new NameValuePairInputCollection {
                        { "Notification", Inputs.CurrentNotification }
                    } );
                    Outputs.Validations.AddRange( SaveNotificationProcessResult.Outputs.Validations );
                }
                catch ( ValidationResultException validationResultException ) {
                    Outputs.Validations.AddRange( validationResultException.Validations );
                    if ( validationResultException.ContainsError() ) {
                        throw new ValidationResultException( string.Format( "Processing {0} resulted in an error", Name ), Outputs.Validations );
                    }
                }
                var HomeSaveNotificationResult = SaveNotificationProcessResult;
                Debugging.DebugWorker.Current.SetVariableValue( "HomeSaveNotificationResult", HomeSaveNotificationResult );
                Debugging.DebugWorker.Current.BeginInstruction( "b60bbb93-3a06-4a57-ace3-6024f91c94a0", "85d667f2-7ed7-4d91-9dff-1c25687fa197" );
                Debugging.DebugWorker.Current.EndProcess();
                Outputs.SessionToken = UiStringConverter.CreateSessionToken( Inputs.CurrentUser );
                return this;
            }
            *catch ( ConcurrencyException ) {
                throw;*
            }

【问题讨论】:

  • 哪一行抛出异常?您可能会在 throw 语句中看到它,但在调用堆栈中查找它实际被抛出的位置 - 或者只是删除整个 try/catch 块(如果您只是捕获要重新抛出的异常它,然后不要抓住它)。
  • // ShapeComment:[Assign Notification as Read][b60bbb93-3a06-4a57-ace3-6024f91c94a0][324e353c-cdd6-488e-8c9c-3420051a06f5] Debugging.DebugWorker.Current.BeginInstruction("b60bbb93 -3a06-4a57-ace3-6024f91c94a0", "324e353c-cdd6-488e-8c9c-3420051a06f5"); Inputs.CurrentNotification.AdoptedBy = Inputs.CurrentUser; Inputs.CurrentNotification.ApprovalStatus = NotificationApprovalStatus.Approved;
  • 那是 3 行。 :) 哪个抛出了异常?
  • 对不起,我们分配当前通知 .adoptedby 和当前通知的地方。批准状态这两个属性是搞砸的,但你可以看到它只是一个分配语句,即使我们在这里看到错误我认为起源是不同的,我猜
  • CurrentNotification 是什么类型?它是你项目中的一个类吗?

标签: c# entity-framework


【解决方案1】:

在异常消息中注意这一点:

影响了意外的行数 (0)

这基本上意味着“我以为我会改变一些东西,但我最终什么都没改变”。

UPDATE MyTable SET MyColumn = "hi" WHERE Id = 5 之类的查询可能会发生这种情况,但没有 Id5 的记录。

如果在这两行之一引发异常:

Inputs.CurrentNotification.AdoptedBy = Inputs.CurrentUser;
Inputs.CurrentNotification.ApprovalStatus = NotificationApprovalStatus.Approved;

这意味着这些属性的 setter 方法正在写入数据库。属性定义如下所示:

User AdoptedBy {
    get {
         //something here
    }
    set {
        //this is writing to the database
    }
}

由于某种原因,它正在更新一些不存在的东西。但是如果没有看到该代码,我们无法告诉您为什么或如何解决它。

所以它取决于Inputs.CurrentNotification 是什么类型的类定义。如果它是您的类之一,那么您可能只是调试并逐步执行该代码。

确实,在属性 getter/setter 中执行任何类型的 I/O 操作都不是一个好主意。

【讨论】:

    猜你喜欢
    • 2018-05-01
    • 2017-03-17
    • 1970-01-01
    • 2016-11-19
    • 2019-03-11
    • 2012-12-01
    相关资源
    最近更新 更多