|
31 | 31 | import com.couchbase.lite.internal.InterfaceAudience; |
32 | 32 | import com.couchbase.lite.internal.RevisionInternal; |
33 | 33 | import com.couchbase.lite.internal.database.ContentValues; |
| 34 | +import com.couchbase.lite.internal.database.sqlite.exception.SQLiteDatabaseLockedException; |
34 | 35 | import com.couchbase.lite.storage.Cursor; |
35 | 36 | import com.couchbase.lite.storage.SQLException; |
36 | 37 | import com.couchbase.lite.storage.SQLiteStorageEngine; |
@@ -63,6 +64,9 @@ public class SQLiteStore implements Store, EncryptableStore { |
63 | 64 |
|
64 | 65 | public static String kDBFilename = "db.sqlite3"; |
65 | 66 |
|
| 67 | + private static final int kTransactionMaxRetries = 10; |
| 68 | + private static final int kTransactionRetryDelay = 50; //50ms |
| 69 | + |
66 | 70 | // Default value for maxRevTreeDepth, the max rev depth to preserve in a prune operation |
67 | 71 | private static final int DEFAULT_MAX_REVS = Integer.MAX_VALUE; |
68 | 72 |
|
@@ -2298,7 +2302,26 @@ protected boolean beginTransaction() { |
2298 | 2302 | try { |
2299 | 2303 | // Outer (level 0) transaction. Use SQLiteDatabase.beginTransaction() |
2300 | 2304 | if (tLevel == 0) { |
2301 | | - storageEngine.beginTransaction(); |
| 2305 | + boolean retry = true; |
| 2306 | + int retries = 0; |
| 2307 | + do { |
| 2308 | + try { |
| 2309 | + storageEngine.beginTransaction(); |
| 2310 | + retry = false; |
| 2311 | + } catch (SQLiteDatabaseLockedException lockedException) { |
| 2312 | + if (++retries > kTransactionMaxRetries) { |
| 2313 | + Log.e(TAG, "Db busy, too many retries, giving up"); |
| 2314 | + throw lockedException; |
| 2315 | + } |
| 2316 | + Log.i(TAG, "Db busy, retrying transaction (#%d)...", retries); |
| 2317 | + try { |
| 2318 | + // sleep 50ms to wait db will be unlocked |
| 2319 | + Thread.sleep(kTransactionRetryDelay); |
| 2320 | + } catch (InterruptedException e) { |
| 2321 | + } |
| 2322 | + } |
| 2323 | + // other exceptions should be caught outer try-catch block |
| 2324 | + } while (retry); |
2302 | 2325 | } |
2303 | 2326 | // Inner (level 1 or higher) transaction. Use SQLite's SAVEPOINT |
2304 | 2327 | else { |
|
0 commit comments