From 23979669900d75bccefb5b4a825882d329a2bd9d Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Mon, 6 Sep 2010 14:37:33 +0200 Subject: some more places are handling SQLITE_BUSY correctly now, test9 still breaks under heavy load --- src/prepared_statement.cpp | 25 +++++++++++++++++-------- tests/test9.cpp | 38 ++++++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/src/prepared_statement.cpp b/src/prepared_statement.cpp index 674fbec..a63a75c 100644 --- a/src/prepared_statement.cpp +++ b/src/prepared_statement.cpp @@ -123,12 +123,12 @@ prepared_stmt::prepared_stmt( sqlite3 *db, string __sql ) : rc = sqlite3_prepare( db, _sql.c_str( ), -1, &_stmt, &tail ); #endif switch( rc ) { - case SQLITE_BUSY: - throw database_locked( ); - case SQLITE_OK: break; + case SQLITE_BUSY: + throw database_locked( ); + default: { ostringstream s; @@ -158,11 +158,20 @@ void prepared_stmt::reset( ) { int rc; assert( _stmt != NULL ); rc = sqlite3_reset( _stmt ); - if( rc != SQLITE_OK ) { - ostringstream s; - s << "sqlite3::prepared_stmt::reset error: " << sqlite3_errmsg( _db ); - string msg = s.str( ); - throw sql_error( msg, _sql ); + switch( rc ) { + case SQLITE_OK: + break; + + case SQLITE_BUSY: + throw database_locked( ); + + default: + { + ostringstream s; + s << "sqlite3::prepared_stmt::reset error: " << sqlite3_errmsg( _db ); + string msg = s.str( ); + throw sql_error( msg, _sql ); + } } } diff --git a/tests/test9.cpp b/tests/test9.cpp index cf61508..5252524 100644 --- a/tests/test9.cpp +++ b/tests/test9.cpp @@ -33,8 +33,8 @@ using namespace sqlite3xx; using namespace std; -const int NOF_PRODUCERS = 1; -const int NOF_CONSUMERS = 1; +const int NOF_PRODUCERS = 10; +const int NOF_CONSUMERS = 10; const int NOF_PRODUCER_TRANSACTIONS = 100; const int NOF_PRODUCER_OPS = 100; const int NOF_CONSUMER_TRANSACTIONS = 100; @@ -64,8 +64,13 @@ static THREAD_FUNC_DECL produce( void *thread_data ) MUTEX_UNLOCK( cout_mutex ); } for( int j = 0; j < NOF_PRODUCER_OPS; j++ ) { - result r = t.prepared( "ins" )( no * 100000 + i * 1000 + j ).exec( ); - assert( r.affected_rows( ) == 1 ); +PRODUCER_INS_AGAIN: + try { + result r = t.prepared( "ins" )( no * 100000 + i * 1000 + j ).exec( ); + assert( r.affected_rows( ) == 1 ); + } catch( database_locked& e ) { + goto PRODUCER_INS_AGAIN; + } } t.commit( ); if( verbose ) { @@ -98,16 +103,21 @@ static THREAD_FUNC_DECL consume( void *thread_data ) MUTEX_UNLOCK( cout_mutex ); } for( int j = 0; j < NOF_CONSUMER_OPS; j++ ) { - result r = t.prepared( "sel" ).exec( ); - int nof_rows = 1; - for( result::const_iterator it = r.begin( ); it < r.end( ); it++, nof_rows++ ) { - int x; - it["x"].to( x ); - } - if( verbose ) { - MUTEX_LOCK( cout_mutex ); - cout << "consumer " << no << " transaction " << i << " got " << nof_rows << " rows." << endl; - MUTEX_UNLOCK( cout_mutex ); +CONSUMER_SELECT_AGAIN: + try { + result r = t.prepared( "sel" ).exec( ); + int nof_rows = 1; + for( result::const_iterator it = r.begin( ); it < r.end( ); it++, nof_rows++ ) { + int x; + it["x"].to( x ); + } + if( verbose ) { + MUTEX_LOCK( cout_mutex ); + cout << "consumer " << no << " transaction " << i << " got " << nof_rows << " rows." << endl; + MUTEX_UNLOCK( cout_mutex ); + } + } catch( database_locked& e ) { + goto CONSUMER_SELECT_AGAIN; } } t.commit( ); -- cgit v1.2.3-54-g00ecf