2015-09-22 8 views
7

एंटीटी फ्रेमवर्क 6.0.0 का उपयोग करके, लेनदेन बंद करते समय मुझे अपवाद दिखाई दे रहा है।लेनदेन वापस रोल करते समय अपवाद - कनेक्शन पहले ही बंद हो गया है?

हमें तालिका में समवर्ती परिवर्तनों में समस्याएं आ रही हैं, इसलिए मैंने इसे एक लेनदेन में लपेट लिया, और अब मुझे रोलबैक पर अपवाद मिल रहे हैं।

कोड:

public LockInfo getSharedLock(string jobid) 
{ 
    using (var myDbContext = new MyDbContext()) 
    { 
     using (var transaction = myDbContext.Database.BeginTransaction()) 
     { 
      try 
      { 
       this.logger.log("Attempting to get shared lock for {0}", jobid); 

       var mylocks = 
        myDbContext.joblocks.Where(j => j.customerid == this.userContext.customerid) 
         .Where(j => j.jobid == jobid) 
         .Where(j => j.operatorid == this.userContext.operatorid); 

       var exclusiveLock = mylocks.FirstOrDefault(
        j => j.lockstatus == LockInfo.LockState.Exclusive); 
       if (exclusiveLock != null) 
       { 
        this.logger.log("{0} already had exclusive lock, ignoring", jobid); 
        return LockInfo.populate(exclusiveLock); 
       } 

       var sharedLock = mylocks.FirstOrDefault(
        j => j.lockstatus == LockInfo.LockState.Shared); 
       if (sharedLock != null) 
       { 
        this.logger.log("{0} already had shared lock, ignoring", jobid)); 
        sharedLock.lockdt = DateTime.Now; 
        myDbContext.SaveChanges(); 

        return LockInfo.populate(sharedLock); 
       } 

       var joblock = new joblock 
       { 
        customerid = this.userContext.customerid, 
        operatorid = this.userContext.operatorid, 
        jobid = jobid, 
        lockstatus = LockInfo.LockState.Shared, 
        sharedLock.lockdt = DateTime.Now 
       }; 

       myDbContext.joblocks.Add(joblock); 
       myDbContext.SaveChanges(); 
       transaction.Commit(); 

       this.logger.log("Obtained shared lock for {0}", jobid); 
       return LockInfo.populate(joblock); 
      } 
      catch (Exception ex) 
      { 
       transaction.Rollback(); 
       this.logger.logException(ex, "Exception in getSharedLock(\"{0}\")", jobid); 
       throw; 
      } 
     } 
    } 
} 

आप प्रवेश देख सकते हैं उपरोक्त कोड में,। हमारे पास डेटाबेस में भी लॉगिंग सक्षम है। लॉग ट्रेस: ​​

=================== 
NORMAL TicketLockController.getLock("AK2015818002WL") 
=================== 
SQL Opened connection at 9/22/2015 2:47:49 PM -05:00 
=================== 
SQL Started transaction at 9/22/2015 2:47:49 PM -05:00 
=================== 
NORMAL Attempting to get shared lock for AK2015818002WL 
=================== 
SQL SELECT TOP (1) [Extent1].[customerid] AS [customerid] 
    ,[Extent1].[jobid] AS [jobid] 
    ,[Extent1].[lockdtdate] AS [lockdtdate] 
    ,[Extent1].[lockdttime] AS [lockdttime] 
    ,[Extent1].[operatorid] AS [operatorid] 
    ,[Extent1].[lockstatus] AS [lockstatus] 
    ,[Extent1].[changes] AS [changes] 
FROM [dbo].[joblock] AS [Extent1] 
WHERE ([Extent1].[customerid] = 'TESTTK') 
    AND ([Extent1].[jobid] = 'AK2015818002WL') 
    AND ([Extent1].[operatorid] = 'ADMIN') 
    AND (N'Exclusive' = [Extent1].[lockstatus]) 
=================== 
SQL SELECT TOP (1) [Extent1].[customerid] AS [customerid] 
    ,[Extent1].[jobid] AS [jobid] 
    ,[Extent1].[lockdtdate] AS [lockdtdate] 
    ,[Extent1].[lockdttime] AS [lockdttime] 
    ,[Extent1].[operatorid] AS [operatorid] 
    ,[Extent1].[lockstatus] AS [lockstatus] 
    ,[Extent1].[changes] AS [changes] 
FROM [dbo].[joblock] AS [Extent1] 
WHERE ([Extent1].[customerid] = 'TESTTK') 
    AND ([Extent1].[jobid] = 'AK2015818002WL') 
    AND ([Extent1].[operatorid] = 'ADMIN') 
    AND (N'Shared' = [Extent1].[lockstatus]) 
=================== 
SQL INSERT [dbo].[joblock] (
    [customerid] 
    ,[jobid] 
    ,[lockdtdate] 
    ,[lockdttime] 
    ,[operatorid] 
    ,[lockstatus] 
    ,[changes] 
    ) 
VALUES (
    @0 
    ,@1 
    ,@2 
    ,@3 
    ,@4 
    ,@5 
    ,NULL 
    ) 
=================== 
SQL Closed connection at 9/22/2015 2:47:50 PM -05:00 
=================== 
EXCEPTION Unhandled exception caught: The underlying provider failed on Rollback. 
=================== 
EXCEPTION Inner Exception: Value cannot be null. 
Parameter name: connection 

दो चयन सफल रहे हैं, तो डालने किसी कारण से विफल हो रहा है। अपवाद फेंकना, और किसी कारण से कनेक्शन रोलबैक() निष्पादित करने से पहले बंद हो रहा है।

कोई विचार क्या मैं गलत कर रहा हूं?

at System.Data.Entity.Core.EntityClient.EntityTransaction.Rollback() 
    at korterra.kt_api.Shared.TicketLockWrangler.getSharedLock(String jobid) 
    at korterra.kt_ws.ApiControllers.Shared.TicketLockController.getSharedLock(TicketLockDTO ticketLockDTO) 
    at lambda_method(Closure , Object , Object[]) 
    at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters) 
    at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments) 
    at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext() 

भीतरी अपवाद के लिए स्टैकट्रेस: ​​स्टैक ट्रेस ====

बाहरी अपवाद के लिए स्टैकट्रेस जोड़ना

====

at System.Data.Entity.Utilities.Check.NotNull[T](T value, String parameterName) 
    at System.Data.Entity.Infrastructure.Interception.DbTransactionInterceptionContext.WithConnection(DbConnection connection) 
    at System.Data.Entity.Infrastructure.Interception.DbTransactionDispatcher.Rollback(DbTransaction transaction, DbInterceptionContext interceptionContext) 
    at System.Data.Entity.Core.EntityClient.EntityTransaction.Rollback() 
+0

पूर्ण अपवाद ToString पोस्ट करें। आपकी त्रुटि लॉगिंग अपर्याप्त है। – usr

+0

इसके अलावा, आप कई मामलों में लेनदेन नहीं कर रहे हैं। क्या यह वास्तव में जानबूझकर है? – usr

+0

मैं मांग पर इसे फिर से नहीं बना सकता। यह ऐसा कुछ है जो हमारे क्यूए पर्यावरण में अंतःस्थापित होता है। मैंने इसे देव में कभी नहीं देखा है। मेरे पास पहले से पोस्ट की गई एकमात्र जानकारी है जो स्टैक ट्रेस है, जो बस इंगित करता है कि मेरे द्वारा पोस्ट किए गए कोड में अपवाद हुआ। –

उत्तर

6

चर्चा के बाद, मैं वापस रोल करने की कोशिश करने से पहले अपवाद लॉगिंग शुरू कर दिया - और यह त्रुटि प्रकट हुई।

लेनदेन deadlocked किया गया था:

Exception in getSharedLock("ticketnumber123456"): An error occurred while updating the entries. See the inner exception for details. 

Inner Exception: An error occurred while updating the entries. See the inner exception for details. 

Inner Exception: Transaction (Process ID 139) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. 

मैं क्या पढ़ रहा हूँ, जब आपके किसी लेन-देन एक गतिरोध शिकार बना दिया गया है बताया से, यह पहले से ही वापस लुढ़का दिया गया है। शायद यही कारण है कि हमें अपवाद मिल रहा है?

यह तय करने के लिए प्रतीत होता है कि जब हमने डेडलॉक किया है, रोलबैक नहीं किया है, या लेनदेन का उपयोग नहीं किया है, और जब हम प्राथमिक कुंजी उल्लंघन प्राप्त करते हैं तो पुनः प्रयास करें।

+0

आपको कोड के इस टुकड़े में रोलबैक को कभी भी कॉल नहीं करना चाहिए। इसके अलावा, यह एक ईएफ बग है। यह दुर्घटनाग्रस्त नहीं होना चाहिए। इसे एक एपीआई उपयोग त्रुटि या एक साफ अपवाद का उपयोग कर कुछ रिपोर्ट करना चाहिए। क्या आप इसके लिए ईएफ रेपो में गिटहब मुद्दा खोल सकते हैं? – usr

+0

मैं वर्तमान में लेनदेन का उपयोग नहीं कर रहा हूं, लेकिन अंतर्निहित रिकॉर्ड बदलते समय बस पुनः प्रयास कर रहा हूं - आशावादी लॉकिंग। –

संबंधित मुद्दे

 संबंधित मुद्दे