Comments (2)
This is really a problem with SQLite3 which is rather mediocre when handling parallel transactions (just like most transactional databases) and the error that you see is not really caused by SQLPP11's connection pools or even by SQLPP11.
The multithreaded test is getting the SQLite3 error SQL_BUSY
with integer code 5.
When handling parallel transactions SQLite3 does (somewhat) optimistic locking. Transactions just go in parallel and when there is a conflict between two of them (that is two transactions try to acquire a write lock), one of them succeeds and the other gets an automatic rollback with SQL_BUSY
. In that respect it is quite similar to PostgreSQL where instead of SQL_BUSY
you get serialization_failure (40001)
or deadlock_detected (40P01)
.
Essentially you have two ways of handling these errors in SQLite3:
Option 1. The quick and dirty solution. For each connection handle that you get (from the pool or by creating it manually) install a busy timeout by calling sqlite3_busy_timeout()
on the native connection under the handle. Something like this:
auto& conn = pool.get();
sqlite3_busy_timeout(conn.native_handle(), 10000); // SQL_BUSY if we cannot acquire lock after 10 seconds
Then use explicit or implicit transactions with SQLite3 and hope that your transactions don't span more than 10 seconds (or whatever timeout you set). You can issue explicitly BEGIN IMMEDIATE/EXCLUSIVE
but it is not really mandatory because by default SQLite3 uses autocommit mode and sqlpp11's explicit transactions create transactions in DEFERRED
mode which is probably good enough.
For SQLite3 I would probably go with with the quick-and-dirty option, because in most cases you are not going to run any complex transactions/queries with SQLite3.
Option 2. Handle automatic transaction rollbacks (i.e. SQL_BUSY) properly and upon getting a rollback retry the whole transaction until it succeeds. We discussed a similar approach for MySQL connection fails and for PostgreSQL transactions here #530 but it is pretty much the same for SQLite3 transaction failures.
If you are interested in the details of SQLite3 transaction handling and why you are getting SQL_BUSY, you can read these two documents:
https://activesphere.com/blog/2018/12/24/understanding-sqlite-busy
https://www.sqlite.org/lang_transaction.html
Actually I have a transaction manager class that retries transactions for PostgreSQL. If someone is interested I can upload it. It is quite simple but works well for PostgreSQL. It can be ported to the other connectors (MySQL and SQLite3), but before that we really need to fix the exceptions thrown by the MySQL/SQLite3 connectors because right now they just throw a generic sqlpp::exception()
so the transaction manager does not have an easy way of detecting the error type.
from sqlpp11.
Okay I understood, thank you!
from sqlpp11.
Related Issues (20)
- Is there any opentracing support in sqlpp,like jaeger?Will it be supported in the future? HOT 1
- how to fix update exception? HOT 23
- How to retrieve the row count of a query result? HOT 6
- mysql does not seem to support the TIME type HOT 4
- Multiple table query error HOT 3
- Mysql prepared_statement.h missing _bind_time_of_day_parameter function HOT 3
- How do I get record with count of references from one to many? HOT 4
- Handling of `::sqlpp::tag::enforce_null_result_treatment` does not seem to be implemented, NULL documentation is erroneous HOT 11
- scripts/sqlite2cpp.py requires insert of nullable column HOT 6
- [Feedback Requested] Results returning optional, string_view, and span HOT 22
- [requesting assistance] Can the same parameter be used in multiple places in the same prepared statement? HOT 13
- [Need assistance] Common Table Expressions with update HOT 2
- Can't find how to use count(1) HOT 3
- head file include question HOT 3
- how to predict const struct sqlpp::result_row_t is or not NULL? HOT 3
- Supporting the BETWEEN operator? HOT 2
- SQLite: Is order by rowid possible? HOT 2
- Title: Error E0140: Too Many Arguments in Function Call in `for_update.h` with VS2022 HOT 3
- Using sqlpp::parameterized_verbatim as lhs in comparison results in segfault. HOT 4
- [Bug] [SQLite] White space at the end of the SQL string makes execute() throw "Sqlite3 connector: Cannot execute multi-statements" HOT 2
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 sqlpp11.