Originally created by @spacedema on GitHub (Jun 22, 2020).
Hi, @JohnEstropia!
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...
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
for async db operation
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
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

- for async db operation

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 18:25:47 +01:00
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.
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
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)
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Originally created by @spacedema on GitHub (Jun 22, 2020).
Hi, @JohnEstropia!
dataStack.perform(asynchronous: { transaction in...try db.perform(synchronous: { transaction in...I'm facing deadlocks very frequent. Attaching screenshots with call stacks
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
But I'm not a big specialist in core data at all, so I would like to hear your opinion about this case
Thanks.
@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.
@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
autoCommitfunction. There are no collides with my changes, so I want to know your opinion about it@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):
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.@spacedema commented on GitHub (Jul 16, 2020):
ok, thanks for the answer