The wrapper of the library SQLITE3 to Harbour, support THEADSAFE, but it is important to use the same handle pSqlite3,
using https://en.wikipedia.org/wiki/Singleton_pattern
An easy example to see;
CLASS TLogSqlite3
CLASSDATA Self
DATA pSqlite3
DATA cErrorSqlite3
METHOD getInstance()
METHOD Open() PROTECTED
METHOD Exec( cSql )
METHOD Close() INLINE ::pSqlite3 := NIL
METHOD InitClass ()
END CLASS
METHOD InitClass CLASS TLogSqlite3
if ::Self = NIL
::Self := Self
::Open()
endif
RETURN Self
METHOD getInstance CLASS TLogSqlite3
RETURN ::Self
METHOD Open( ) CLASS TLogSqlite3
Local lRet := .T.
::pSqlite3 := sqlite3_open( hb_dirBase() + "text.db", .T. )
IF !( sqlite3_errcode( ::pSqlite3 ) == SQLITE_OK )
::cErrorSqlite3 := sqlite3_errmsg( ::pSqlite3 )
lRet := .T.
ENDIF
RETURN lRet
METHOD Exec( cSql ) CLASS TLogSqlite3
Local cSql, lRet := .T., cOldDataFormat, cOldTimeFormat
Local cWarning := ""
IF sqlite3_exec( ::pSqlite3, "BEGIN TRANSACTION;") == SQLITE_OK
IF sqlite3_exec( ::pSqlite3, cSql ) != SQLITE_OK
::cErrorSqlite3 := sqlite3_errmsg( ::pSqlite3 )
sqlite3_exec( ::pSqlite3, " ROLLBACK;")
lRet := .F.
ENDIF
IF empty( ::cErrorSqlite3 )
sqlite3_exec( ::pSqlite3, "COMMIT;" )
lRet := .T.
ENDIF
ENDIF
RETURN lRet
For use in you aplicattion with threads ;
oSqlite3 := TLogSqlite3():getInstance()
oSqlite3:Exec( cSql )
The explanation is very simple.
If the TLogSqlite3 object instance per thread, then insert each other will be blocked, because the table is locked, not being theadSafe.
But for compliance Thread Safe, need to use the same variable pSqlite3 for all calls. Using the singleton pattern, we solve the problem of locking the table.
No hay comentarios:
Publicar un comentario