Buggy code:
return new Object [ ] { "error" , rrem . get ( "errorType" ) , rrem . get ( "errorReason" ) } ; } Log . i ( TAG , "Sync:<seq2seq4repair_space>applying<seq2seq4repair_space>removed<seq2seq4repair_space>data" ) ; remove ( rrem ) ; con . publishProgress ( sync_small_objects_message ) ; Log . i ( TAG , "Sync:<seq2seq4repair_space>collection<seq2seq4repair_space>small<seq2seq4repair_space>changes" ) ; JSONObject lchg = changes ( ) ; JSONObject sch = new JSONObject ( ) ; sch . put ( "changes" , lchg ) ; Log . i ( TAG , "Sync:<seq2seq4repair_space>sending<seq2seq4repair_space>and<seq2seq4repair_space>receiving<seq2seq4repair_space>small<seq2seq4repair_space>changes" ) ; JSONObject rchg = mServer . applyChanges ( sch ) ; if ( rchg == null ) { Log . i ( TAG , "Sync:<seq2seq4repair_space>error<seq2seq4repair_space>-<seq2seq4repair_space>returning" ) ; return null ; } if ( rchg . has ( "errorType" ) ) { Log . i ( TAG , "Sync:<seq2seq4repair_space>error<seq2seq4repair_space>-<seq2seq4repair_space>returning" ) ; return new Object [ ] { "error" , rchg . get ( "errorType" ) , rchg . get ( "errorReason" ) } ; } Log . i ( TAG , "Sync:<seq2seq4repair_space>mergin<seq2seq4repair_space>small<seq2seq4repair_space>changes" ) ; mergeChanges ( lchg , rchg ) ; con . publishProgress ( sync_download_chunk ) ; while ( true ) { Log . i ( TAG , "Sync:<seq2seq4repair_space>downloading<seq2seq4repair_space>chunked<seq2seq4repair_space>data" ) ; JSONObject chunk = mServer . chunk ( ) ; if ( chunk == null ) { Log . i ( TAG , "Sync:<seq2seq4repair_space>error<seq2seq4repair_space>-<seq2seq4repair_space>returning" ) ; return null ; } if ( chunk . has ( "errorType" ) ) { Log . i ( TAG , "Sync:<seq2seq4repair_space>error<seq2seq4repair_space>-<seq2seq4repair_space>returning" ) ; return new Object [ ] { "error" , chunk . get ( "errorType" ) , chunk . get ( "errorReason" ) } ; } Log . i ( TAG , "Sync:<seq2seq4repair_space>applying<seq2seq4repair_space>chunked<seq2seq4repair_space>data" ) ; applyChunk ( chunk ) ; if ( chunk . getBoolean ( "done" ) ) { break ; } } con . publishProgress ( sync_upload_chunk ) ; while ( true ) { Log . i ( TAG , "Sync:<seq2seq4repair_space>collecting<seq2seq4repair_space>chunked<seq2seq4repair_space>data" ) ; JSONObject chunk = chunk ( ) ; JSONObject sech = new JSONObject ( ) ; sech . put ( "chunk" , chunk ) ; Log . i ( TAG , "Sync:<seq2seq4repair_space>sending<seq2seq4repair_space>chunked<seq2seq4repair_space>data" ) ; mServer . applyChunk ( sech ) ; if ( chunk . getBoolean ( "done" ) ) { break ; } } JSONArray c = sanityCheck ( ) ; if ( c == null ) { return new Object [ ] { "error" , 200 , "sanity<seq2seq4repair_space>check<seq2seq4repair_space>error<seq2seq4repair_space>on<seq2seq4repair_space>local" } ; } JSONArray s = mServer . sanityCheck ( ) ; if ( s . getString ( 0 ) . equals ( "error" ) ) { return new Object [ ] { "error" , 200 , "sanity<seq2seq4repair_space>check<seq2seq4repair_space>error<seq2seq4repair_space>on<seq2seq4repair_space>server" } ; } boolean error = false ; for ( int i = 0 ; i < ( s . getJSONArray ( 0 ) . length ( ) ) ; i ++ ) { if ( ( c . getJSONArray ( 0 ) . getLong ( i ) ) != ( s . getJSONArray ( 0 ) . getLong ( i ) ) ) { error = true ; } } for ( int i = 1 ; i < ( s . length ( ) ) ; i ++ ) { if ( ( c . getLong ( i ) ) != ( s . getLong ( i ) ) ) { error = true ; } } if ( error ) { return new Object [ ] { "error" , 200 , ( ( "sanity<seq2seq4repair_space>check<seq2seq4repair_space>failed:\nlocal:<seq2seq4repair_space>" + ( c . toString ( ) ) ) + "\nremote:<seq2seq4repair_space>" ) + ( s . toString ( ) ) } ; } con . publishProgress ( sync_finish_message ) ; Log . i ( TAG , "Sync:<seq2seq4repair_space>sending<seq2seq4repair_space>finish<seq2seq4repair_space>command" ) ; long mod = mServer . finish ( ) ; if ( mod == 0 ) { return new Object [ ] { "finishError" } ; } Log . i ( TAG , "Sync:<seq2seq4repair_space>finishing" ) ; finish ( mod ) ; mCol . getDb ( ) . getDatabase ( ) . setTransactionSuccessful ( ) ; } finally { <START_BUG> mCol . getDb ( ) . getDatabase ( ) . setTransactionSuccessful ( ) ; <END_BUG> } } catch ( JSONException e ) { throw new RuntimeException ( e ) ; } catch ( IllegalStateException e ) { throw new RuntimeException ( e ) ; } catch ( IOException e ) { throw new RuntimeException ( e ) ; } return new Object [ ] { "success" } ; } private JSONArray meta ( ) { } private JSONObject changes ( ) { } private JSONObject applyChanges ( JSONObject changes ) { } private void mergeChanges ( JSONObject lchg , JSONObject rchg ) { } private JSONArray sanityCheck ( ) { } private String usnLim ( ) { } private long finish ( ) { } private long finish ( long mod ) { } private void prepareToChunk ( ) { } private Cursor cursorForTable ( String table ) { } private List < Integer > columnTypesForQuery ( String table ) { } private JSONObject chunk ( ) { } private void applyChunk ( JSONObject chunk ) { } private JSONObject removed ( ) { } private JSONObject start ( int minUsn , boolean lnewer , JSONObject graves ) { } private void remove ( JSONObject graves ) { } private JSONArray getModels ( ) { } private void mergeModels ( JSONArray rchg ) { } private JSONArray getDecks ( ) { } private void mergeDecks ( JSONArray rchg ) { } private JSONArray getTags ( ) { } private void mergeTags ( JSONArray tags ) { } private void mergeRevlog ( JSONArray logs ) { } private ArrayList < Object [ ] > newerRows ( JSONArray data , String table , int modIdx ) { } private void mergeCards ( JSONArray cards ) { } private void mergeNotes ( JSONArray notes ) { } private JSONObject getConf ( ) { } private void mergeConf ( JSONObject conf ) { }

Fix:
mCol . getDb ( ) . getDatabase ( ) . endTransaction ( ) ;