Deadlocks #334

Closed
opened 2025-12-29 15:29:20 +01:00 by adam · 5 comments
Owner

Originally created by @spacedema on GitHub (Jun 22, 2020).

Hi, @JohnEstropia!

  1. I have long running operation with fetch from api -> local db update -> fetch from api -> local db update. All db updates are asynchronous:
    dataStack.perform(asynchronous: { transaction in...
  2. At the same time I do some typical things like delete or update record from db. In this scenario I'm using synchronous operations cause all of them are lightweight (for example update one record or delete one record):
    try db.perform(synchronous: { transaction in...
    I'm facing deadlocks very frequent. Attaching screenshots with call stacks
  • for sync db operation
    SyncOperationCallStack
  • for async db operation
    AsyncOperationCallStack

And I see that problem is in autoCommit() in AsynchronousDataTransaction. I tried to rewrite it as follows and seems that everything is ok, deadlocks are gone

    internal func autoCommit(_ completion: @escaping (_ hasChanges: Bool, _ error: CoreStoreError?) -> Void) {
        
        self.isCommitted = true        
        self.context.saveAsynchronouslyWithCompletion { (hasChanges, error) -> Void in
            
            completion(hasChanges, error)
            self.result = (hasChanges, error)
            self.context.reset()
        }
    }

But I'm not a big specialist in core data at all, so I would like to hear your opinion about this case

Thanks.

Originally created by @spacedema on GitHub (Jun 22, 2020). Hi, @JohnEstropia! 1. I have long running operation with fetch from api -> local db update -> fetch from api -> local db update. All db updates are asynchronous: `dataStack.perform(asynchronous: { transaction in...` 2. At the same time I do some typical things like delete or update record from db. In this scenario I'm using synchronous operations cause all of them are lightweight (for example update one record or delete one record): `try db.perform(synchronous: { transaction in...` I'm facing deadlocks very frequent. Attaching screenshots with call stacks - for sync db operation ![SyncOperationCallStack](https://user-images.githubusercontent.com/7204319/85264367-43d07980-b479-11ea-911e-50ac5d0eb882.png) - for async db operation ![AsyncOperationCallStack](https://user-images.githubusercontent.com/7204319/85264404-52b72c00-b479-11ea-9041-b5243ff41484.png) And I see that problem is in autoCommit() in AsynchronousDataTransaction. I tried to rewrite it as follows and seems that everything is ok, deadlocks are gone ``` internal func autoCommit(_ completion: @escaping (_ hasChanges: Bool, _ error: CoreStoreError?) -> Void) { self.isCommitted = true self.context.saveAsynchronouslyWithCompletion { (hasChanges, error) -> Void in completion(hasChanges, error) self.result = (hasChanges, error) self.context.reset() } } ``` But I'm not a big specialist in core data at all, so I would like to hear your opinion about this case Thanks.
adam added the question label 2025-12-29 15:29:20 +01:00
adam closed this issue 2025-12-29 15:29:20 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Jul 16, 2020):

I don't really have other suggestions here but to avoid using perform(synchronous:).
The synchronous and asynchronous transactions will collide with each other eventually if you use them together.

@JohnEstropia commented on GitHub (Jul 16, 2020): I don't really have other suggestions here but to avoid using `perform(synchronous:)`. The synchronous and asynchronous transactions will collide with each other eventually if you use them together.
Author
Owner

@spacedema commented on GitHub (Jul 16, 2020):

Yes, I know it is highly recommended to use asynchronous transactions, but now project has synchronous transactions too.
The main question was about autoCommit function. There are no collides with my changes, so I want to know your opinion about it

@spacedema commented on GitHub (Jul 16, 2020): Yes, I know it is highly recommended to use asynchronous transactions, but now project has synchronous transactions too. The main question was about `autoCommit` function. There are no collides with my changes, so I want to know your opinion about it
Author
Owner

@JohnEstropia commented on GitHub (Jul 16, 2020):

We can't remove the DispatchGroup here. Without that the synchronous transactions will violate CoreStores transaction serialized processing and stops being a transaction altogether (e.g. A sync transaction can run while another asyn transaction is in progress)

@JohnEstropia commented on GitHub (Jul 16, 2020): We can't remove the DispatchGroup here. Without that the synchronous transactions will violate CoreStores transaction serialized processing and stops being a transaction altogether (e.g. A sync transaction can run while another asyn transaction is in progress)
Author
Owner

@JohnEstropia commented on GitHub (Jul 16, 2020):

If you really want to bypass transactions like this, feel free to use DataStack.beginUnsafe(), which creates "transactions" that you can manually manage the threading for.

@JohnEstropia commented on GitHub (Jul 16, 2020): If you really want to bypass transactions like this, feel free to use `DataStack.beginUnsafe()`, which creates "transactions" that you can manually manage the threading for.
Author
Owner

@spacedema commented on GitHub (Jul 16, 2020):

ok, thanks for the answer

@spacedema commented on GitHub (Jul 16, 2020): ok, thanks for the answer
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#334