This is true for every SQL database. Push conflicting transactions hard enough and you'll need a retry loop. In Postgres you'll see row-level MVCC detecting a write conflict and have the exact same end result. SQLite's locking is just coarser grained, and tends to trigger with less load.
https://www.postgresql.org/docs/15/mvcc-serialization-failur...