Secure access to databases under Android multithreading (Concurrent database access)

Source: Internet
Author: User

Assuming you have your own sqliteopenhelper: 

1  Public class extends Sqliteopenhelper {...}

Now you want to the write data to database in separate threads:

1 //Thread 12Context context =Getapplicationcontext ();3Databasehelper helper =NewDatabasehelper (context);4Sqlitedatabase Database =helper.getwritabledatabase ();5 Database.insert (...);6 database.close ();7 8  //Thread 29Context context =Getapplicationcontext ();TenDatabasehelper helper =NewDatabasehelper (context); OneSqlitedatabase Database =helper.getwritabledatabase (); A Database.insert (...); -Database.close ();

You'll get following message in your logcat and one of your changes would not be written:

Android.database.sqlite. Sqlitedatabaselockedexception5)

This is happening because every time to create new SQLiteOpenHelper object you are actually making new database connection. If you try to write to the database from actual distinct connections at the same time, one would fail.

To use the database with multiple threads we need to make sure we is using one database connection.

Let's make Singleton class which would hold and DatabaseManager return a single SQLiteOpenHelper object.

1  Public classDatabasemanager {2 3     Private StaticDatabasemanager instance;4     Private StaticSqliteopenhelper Mdatabasehelper;5 6      Public Static synchronized voidinitializeinstance (Sqliteopenhelper helper) {7         if(Instance = =NULL) {8Instance =NewDatabasemanager ();9Mdatabasehelper =Helper;Ten         } One     } A  -      Public Static synchronizedDatabasemanager getinstance () { -         if(Instance = =NULL) { the             Throw NewIllegalStateException (Databasemanager.class. Getsimplename () + -"Isn't initialized, call initialize (..) Method first. "); -         } -  +         returninstance; -     } +  A      Public synchronizedsqlitedatabase getdatabase () { at         returnmdatabasehelper.getwritabledatabase (); -     } -  -}
Updated code which write data to database in separate threads would look like this.
1  //In your application class2Databasemanager.initializeinstance (NewDatabasehelper ());3 4  //Thread 15Databasemanager Manager =databasemanager.getinstance ();6Sqlitedatabase Database =manager.getdatabase ()7 Database.insert (...);8 database.close ();9 Ten  //Thread 2 OneDatabasemanager Manager =databasemanager.getinstance (); ASqlitedatabase Database =manager.getdatabase () - Database.insert (...); -Database.close ();

This would bring you another crash:

Java.lang. IllegalStateException: Attempt to re-open an already-closed objectsqlitedatabase    

Since we is using only one database connection, method getDatabase() return same instance of the object for and SQLiteDatabase Thread1 Thread2 . What are happening, may Thread1 close database, and while is Thread2 still using it. That's why we have IllegalStateException crash.

We need to make sure No-one are using database and only then close it. Some folks on Stackoveflow recommended to never close your SQLiteDatabase . This would honor you with following logcat message. So I don ' t think the is good idea at all.

Leak foundcaused byJava.lang. IllegalStateExceptionSqlitedatabase created and never closed

Working sample:
1  Public classDatabasemanager {2 3     PrivateAtomicinteger Mopencounter =NewAtomicinteger ();4 5     Private StaticDatabasemanager instance;6     Private StaticSqliteopenhelper Mdatabasehelper;7     Privatesqlitedatabase mdatabase;8 9      Public Static synchronized voidinitializeinstance (Sqliteopenhelper helper) {Ten         if(Instance = =NULL) { OneInstance =NewDatabasemanager (); AMdatabasehelper =Helper; -         } -     } the  -      Public Static synchronizedDatabasemanager getinstance () { -         if(Instance = =NULL) { -             Throw NewIllegalStateException (Databasemanager.class. Getsimplename () + +"Isn't initialized, call Initializeinstance (..) Method first. "); -         } +  A         returninstance; at     } -  -      Public synchronizedsqlitedatabase OpenDatabase () { -         if(Mopencounter.incrementandget () = = 1) { -             //Opening New Database -Mdatabase =mdatabasehelper.getwritabledatabase (); in         } -         returnmdatabase; to     } +  -      Public synchronized voidcloseDatabase () { the         if(Mopencounter.decrementandget () = = 0) { *             //Closing Database $ mdatabase.close ();Panax Notoginseng  -         } the     } +}

and use it as follows.

 1  sqlitedatabase database = 2  database.insert (...);  3   Database.close (); Don ' t close it directly!  4  databasemanager.getinstance (). CloseDatabase (); //  correct"  

Every time need database you should call openDatabase() method of DatabaseManager class. Inside This method, we had a counter, which indicate how many times database is opened. If it equals to one, it means we need to the create new database, if not, the database is already created.

The same happens in closeDatabase() method. Every time we call the This method, counter was decreased, whenever it goes to zero, we are closing database.

Now you should is able to use your database and is sure-it ' s thread safe.

From:github

Secure access to databases under Android multithreading (Concurrent database access)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.