Thanks.

You're right. I tried close on the readOnlyDB and it closed "both" database
object ;-(

Still not sure how to deal with the readlock then? ;-(

2009/10/27 mirko <[email protected]>

>
> Hi Mariano,
>
> I use close only once. The DB object is held in an Android service.
> When the service stops the DB object is closed. I think you should not
> have two opened DB objects at the same time.
>
> Mirko
>
> On 23 Okt., 22:09, Mariano Kamp <[email protected]> wrote:
> > Hey Mirko,
> >   thank you very much for taking the time to give me such a detailed and
> > easy to understand answer.
> >
> >   I think that I already have implemented my code the way you describe as
> I
> > originally started out with the Notepad
> > example<
> http://developer.android.com/guide/tutorials/notepad/notepad-ex1.html>and
> > that does it the same way. Except that I don't use transactions.
> > However
> > in the lock situation from above (see the two stack traces I quoted
> above)
> > the concurrent accesses were reads, so the transactions idea doesn't
> apply,
> > or does it?
> >
> >   Reading your mail I thought of something else. Maybe I should open a
> read
> > only database? That would be a separate instance then.
> >
> >   mAllPurposeDatabase = dbOpenerHelper.getWritableDatabase();
> >   mSlowQueryDatabase =  dbOpenerHelper.getReadableDatabase();
> >
> >   And then I will direct the slow queries always to the 2nd instance. It
> > wouldn't matter much if the database contains old data, it's just used
> for
> > search. I may setLockingEnabled()<
> http://developer.android.com/reference/android/database/sqlite/SQLite...
> )>to
> > false, but as the queries are slow it probably won't matter much.
> >
> >   Something completely different. Do you use close() on the database at
> all?
> > If so, when?
> >
> > Cheers,
> > Mariano
> >
> > On Fri, Oct 23, 2009 at 7:16 PM, mirko <[email protected]>
> wrote:
> >
> > > Hi Mariano,
> >
> > > I had the same problems with my app. After reading a little bit on the
> > > SQLite Website my understanding was that locking is done with process
> > > (thread) locks. So there are many reader treads possible, but only one
> > > writer thread. For this reason your SQLiteDatabase object needs to be
> > > a singleton. I think otherwise the database file will be opened
> > > several times. In my app I get the singleton with:
> >
> > > mDatabase = dbOpenerHelper.getWritableDatabase();
> >
> > > This is only called once and every call to the Database uses the same
> > > mDatabase object,
> >
> > > Every time I read in the database I do not open a transaction, only a
> > > cursor, like this:
> >
> > >        public static PlaylistItem queryCurrentTrackInDB(SQLiteDatabase
> db,
> > > String playlistID) {
> > >                PlaylistItem ret = null;
> > >                String whereClause = PlaylistItem.COL_PLAYLIST_ID +
> "=?";
> > >                String[] whereValues = new String[] { playlistID };
> > >                String orderClause = PlaylistItem.COL_CURRENT_TRACK + "
> > > DESC," +
> > > PlaylistItem.COL_NUMBER;
> > >                Cursor cur = db.query(IConstants.PLAYLIST_TABLE, null,
> > > whereClause,
> > > whereValues, null, null, orderClause, "2");
> > >                if (cur.moveToFirst()) {
> > >                        ret = new PlaylistItem(cur);
> > >                }
> > >                cur.close();
> > >                return ret;
> > >        }
> >
> > > Every time I write to the database I use a transaction:
> >
> > >        public static boolean deletePlaylistByID(SQLiteDatabase db,
> String
> > > playlistID) {
> > >                db.beginTransaction();
> > >                int r = 0;
> > >                try {
> > >                        String whereClause =
> PlaylistItem.COL_PLAYLIST_ID +
> > > "=?";
> > >                        String[] whereValues = new String[] {
> playlistID};
> > >                        r = db.delete(IConstants.PLAYLIST_TABLE,
> > > whereClause, whereValues);
> > >                        db.setTransactionSuccessful();
> > >                } finally {
> > >                        db.endTransaction();
> > >                }
> > >                return r > 0;
> > >        }
> >
> > > I have a lot of concurrency in my app and after changing it the
> > > described way it works quite well.
> >
> > > Mirko
> >
> > > On 23 Okt., 18:14, Mariano Kamp <[email protected]> wrote:
> > > > Hi,
> >
> > > >   I have implemented a slow search provider that queries my database.
> Now
> > > > when at the same time I do another read access my applications stalls
> > > (ANR).
> >
> > > >   It's both read and I don't see why there should be a lock. What are
> my
> > > > options to get a little more concurrency here?
> >
> > > > Cheers,
> > > > Mariano
> >
> > > > Here are the two threads that block each other.
> >
> > > > One:
> > > > "main" prio=5 tid=3 WAIT
> > > >   | group="main" sCount=1 dsCount=0 s=N obj=0x4001db08 self=0xbc48
> > > >   | sysTid=2680 nice=0 sched=0/0 handle=-1343996920
> > > >   at java.lang.Object.wait(Native Method)
> > > >   - waiting on <0x271f30> (a java.lang.VMThread)
> > > >   at java.lang.Thread.parkFor(Thread.java:1499)
> > > >   at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48)
> > > >   at sun.misc.Unsafe.park(Unsafe.java:319)
> > > >   at
> java.util.concurrent.locks.LockSupport.park(LockSupport.java:117)
> > > >   at
> >
> > >
> java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:680)
> > > >   at
> >
> > >
> java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:710)
> > > >   at
> >
> > >
> java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1040)
> > > >   at
> >
> > >
> java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:193)
> > > >   at
> > > java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:252)
> > > >   at
> android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:292)
> > > >   at
> >
> > >
> android.database.sqlite.SQLiteDatabase.addSQLiteClosable(SQLiteDatabase.java:221)
> > > >   at android.database.sqlite.SQLiteProgram.<i
> > > > nit>(SQLiteProgram.java:57)
> > > >   at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:49)
> > > >   at
> >
> > >
> android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:49)
> > > >   at
> >
> > >
> android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1118)
> > > >   at
> > > >
> android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1092)
> > > >   at com.newsrob.DB.findCursorByQueryString(DB.java:419)
> > > >   at
> com.newsrob.EntryManager.getArticleAsCursor(EntryManager.java:1010)
> > > >   at
> >
> > >
> com.newsrob.activities.ShowArticleActivity.onCreate(ShowArticleActivity.java:81)
> > > >   at
> >
> > >
> android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
> > > >   at
> >
> > >
> android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
> > > >   at
> > > >
> android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
> > > >   at android.app.ActivityThread.access$2100(ActivityThread.java:116)
> > > >   at
> android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
> > > >   at android.os.Handler.dispatchMessage(Handler.java:99)
> > > >   at android.os.Looper.loop(Looper.java:123)
> > > >   at android.app.ActivityThread.main(ActivityThread.java:4203)
> > > >   at java.lang.reflect.Method.invokeNative(Native Method)
> > > >   at java.lang.reflect.Method.invoke(Method.java:521)
> > > >   at
> >
> > >
> com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
> > > >   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
> > > >   at dalvik.system.NativeStart.main(Native Method)
> >
> > > > Two:
> > > > "Binder Thread #4" prio=5 tid=17 NATIVE
> > > >   | group="main" sCount=1 dsCount=0 s=N obj=0x432685c8 self=0x231ee8
> > > >   | sysTid=2690 nice=10 sched=0/0 handle=2315224
> > > >   at android.database.sqlite.SQLiteQuery.native_fill_window(Native
> > > Method)
> > > >   at
> android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:75)
> > > >   at
> > > android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:288)
> > > >   at
> android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:269)
> > > >   at
> > > android.database.AbstractCursor.moveToPosition(AbstractCursor.java:171)
> > > >   at
> android.database.AbstractCursor.moveToNext(AbstractCursor.java:256)
> > > >   at
> > > >
> com.newsrob.search.SearchProvider.getSuggestions(SearchProvider.java:80)
> > > >   at com.newsrob.search.SearchProvider.query(SearchProvider.java:68)
> > > >   at
> >
> > >
> android.content.ContentProvider$Transport.bulkQuery(ContentProvider.java:116)
> > > >   at
> >
> > >
> android.content.ContentProviderNative.onTransact(ContentProviderNative.java:97)
> > > >   at android.os.Binder.execTransact(Binder.java:287)
> > > >   at dalvik.system.NativeStart.run(Native Method)
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to