Comments (5)
In later attempts, I set allowsUnsafeTransactions
to true
But I found that when writeWithoutTransaction
or asyncWriteWithoutTransaction
is executed, SchedulingWatchdog
is released, and its life cycle only exists within the closure of the above method. This results in me being unable to use the db
object within the trailing closure of saveImage
.
Does this mean that no matter what method, I can't take db
to other places?
from grdb.swift.
Hello @rakuyoMo,
Does this mean that no matter what method, I can't take
db
to other places?
That's exactly it. The documentation of asyncWriteWithoutTransaction(_:)
states:
The
Database
argument to theupdates
closure argument is valid only during the execution of the closure. Do not store or return the database connection for later use.
This constraint currently lives in the documentation. As soon as the Swift language makes it possible to declare that some values can't be escaped, GRDB will make sure the sample code does not even compile.
If you want to perform further database operations, perform another database access.
In later attempts, I set
allowsUnsafeTransactions
to true.
It is not easy to perform two writes in two distinct persistence systems, and recover from an error in one of them. It's even more difficult when one of the system is asynchronous (saveImage
).
I can't really provide advice on your best way to solve this. Just remember that GRDB transactions like to be synchronous. You can try to make them asynchronous with allowsUnsafeTransactions
, but things will just turn more difficult. In particular, concurrent database access to the same DatabaseQueue
might interfere in really bad ways. You might avoid this by using a specific DatabaseQueue
instance. But now you'll face the risk of busy errors (due to the risk of parallel writes), and lose database observation (due to multiple connection instances). Pick up your battle wisely.
from grdb.swift.
Just remember that GRDB transactions like to be synchronous.
When I use the writeWithoutTransaction
method, even though the trailing closure of saveImage
and try db.beginTransaction()
are executed in the main thread, SchedulingWatchdog
will still be released because of a thread switch in the middle.
In fact, when I comment out the code that prevents me from performing the operation, the database can be written to normally, does this mean that this is just a risky operation and it is not absolutely dangerous?
does this mean that this is just a risky operation and it is not absolutely dangerous?
Well, I think it's an unrealistic idea, and just being risky is enough for it to be banned. At least this is not how the issue should be described or led in this direction.
@groue Or is there a way to achieve the following:
-
After allowing back to the thread that created the database connection, add a new
SchedulingWatchdog
object.Use the
writeWithoutTransaction
synchronization method to create a connection on the main thread, because the thread will not be released, the program just switches between different threads, and will eventually return to the main thread, so you can try to re-add theSchedulingWatchdog
object? -
Regarding the
asyncWriteWithoutTransaction
method, similarly, if the thread that creates the database connection is not released after switching threads, can theSchedulingWatchdog
object be restored when we return to this thread?
from grdb.swift.
Can you provide some clues as to when SchedulingWatchdog
will be released? Or I could figure out a way to keep it there.
from grdb.swift.
Just remember that GRDB transactions like to be synchronous.
I should have said it differently. When you perform a database access, whether it is synchronous or asynchronous, database operations are always executed in a closure that accepts a Database
argument. This closure is synchronous. You must not perform async work there - at least no async work that escapes the Database
from the closure.
This is how it works. This is explicitly documented, as I mentioned above. This will not change.
I'm not sure it is useful to focus of SchedulingWatchdog
, which is an internal tool. Its goal is to help detect misuses of a Database
, such as escaping it. If it prevents you from using the db
value from the saveImage
completion block, well that's exactly its job.
As I said above:
It is not easy to perform two writes in two distinct persistence systems, and recover from an error in one of them. It's even more difficult when one of the system is asynchronous (
saveImage
).
You can try to keep on bending GRDB into supporting unsafe operations, but, again, as I said above:
Pick up your battle wisely.
For example, did you consider refactoring saveImage
into a synchronous method? Or did you consider performing an asynchronous call to saveImage
and then one single database access in its completion block? Or to perform two transactions (one before and one after saveImage
)?
Anyway: as long as you try to perform an async operation in the middle of one single database transaction, you'll face difficulties that GRDB has no intention to help dealing with. This would be against all the concurrency safety measures provided by the library, which aim at the safety of your user's data. Either refactor your code, or live with unsupported techniques that might break any time.
from grdb.swift.
Related Issues (20)
- Privacy Manifest: Entry missing for accessing file timestamps via creationDate API HOT 4
- When transaction updating multiple records in the database, if one of the records does not exist, it leads to update failure. HOT 4
- Avoid conflict with other SPM packages by renaming the CSQLite SPM target
- ValueObservation.tracking called on the updating thread HOT 5
- GRDB does not seem to copy over all rows when inserting within a migration HOT 4
- Unable to decode database NULL value as Swift nil value of type Int? when using ScopeAdapter built from splittingRowAdapters HOT 13
- PlayerRequest.swift is identical in GRDBAsyncDemo and GRDBCombineDemo HOT 4
- App crashes with many (not all) users running iOS 17.4.1 HOT 8
- Library fails to compile when targeting Linux using a SQLite library that doesn't support snapshots HOT 3
- 0xdead10cc prevention — `checkForSuspensionViolation` on every `Statement.step` HOT 6
- Weird db read issue HOT 7
- Error for query count grouped HOT 4
- GRDB 6 missing DatabasePool/DatabaseQueue interchangeability HOT 3
- Thread running at User-initiated quality-of-service class waiting on a thread without a QoS class specified (base priority 0). Investigate ways to avoid priority inversions HOT 1
- [best practices] How can insert a same type of record into 2 tables HOT 8
- Using experimental CTE
- How to temporarily disable observing changes? HOT 5
- Does cancelling a ValueObservation guarantee that it will never notify any more value?
- Async task with `AsyncStream` in command line app exits early without error during writing HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from grdb.swift.