|
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,10 @@ public class SQLiteStore implements Store, EncryptableStore { |
63 | 64 |
|
64 | 65 | public static String kDBFilename = "db.sqlite3"; |
65 | 66 |
|
| 67 | + private static final int kSQLiteBusyTimeout = 5000; // 5sec - Currently not used - default: 2.5sec |
| 68 | + private static final int kTransactionMaxRetries = 10; |
| 69 | + private static final int kTransactionRetryDelay = 50; //50ms |
| 70 | + |
66 | 71 | // Default value for maxRevTreeDepth, the max rev depth to preserve in a prune operation |
67 | 72 | private static final int DEFAULT_MAX_REVS = Integer.MAX_VALUE; |
68 | 73 |
|
@@ -2298,7 +2303,26 @@ protected boolean beginTransaction() { |
2298 | 2303 | try { |
2299 | 2304 | // Outer (level 0) transaction. Use SQLiteDatabase.beginTransaction() |
2300 | 2305 | if (tLevel == 0) { |
2301 | | - storageEngine.beginTransaction(); |
| 2306 | + boolean retry = true; |
| 2307 | + int retries = 0; |
| 2308 | + do { |
| 2309 | + try { |
| 2310 | + storageEngine.beginTransaction(); |
| 2311 | + retry = false; |
| 2312 | + } catch (SQLiteDatabaseLockedException lockedException) { |
| 2313 | + if (++retries > kTransactionMaxRetries) { |
| 2314 | + Log.e(TAG, "Db busy, too many retries, giving up"); |
| 2315 | + throw lockedException; |
| 2316 | + } |
| 2317 | + Log.i(TAG, "Db busy, retrying transaction (#%d)...", retries); |
| 2318 | + try { |
| 2319 | + // sleep 50ms to wait db will be unlocked |
| 2320 | + Thread.sleep(kTransactionRetryDelay); |
| 2321 | + } catch (InterruptedException e) { |
| 2322 | + } |
| 2323 | + } |
| 2324 | + // other exceptions should be caught outer try-catch block |
| 2325 | + } while (retry); |
2302 | 2326 | } |
2303 | 2327 | // Inner (level 1 or higher) transaction. Use SQLite's SAVEPOINT |
2304 | 2328 | else { |
|
0 commit comments