Afaik,你不能因爲每個線程管理自己的連接。
如果您在這些操作之間有這種依賴關係,那麼您可能想同步它們。
例如如果作業A在作業B和作業B的數據庫連接失敗之前完成,該怎麼辦?您的數據將不再同步。你還需要其他工作的邏輯。 另外,作家是互斥的。
我會建議創建一個可以在事務中運行runnables列表的實用程序類。每個作業完成後,將一個Runnable排入此實用程序。這些可運行的程序包括實際的數據庫命令。
當最後一個到達(這取決於您的依賴性邏輯)時,該實用程序將運行事務中的所有可運行參數。
示例實現可能是這樣的:(我用一個簡單的計數器,但是你可能需要一個更復雜的邏輯)
class DbBundle {
AtomicInteger mLatch;
List<Runnable> mRunnables = new ArrayList();
DbBundle(int numberOfTx) {
mLatch = new AtomicInteger(numberOfTx);
}
void cancel() {
mLatch.set(-1); // so decrement can never reach 0 in submit
}
boolean isCanceled() {
mLatch.count() < 0;
}
void submit(Runnable runnable) {
mRunnables.add(runnable);
if (mLatch.decrementAndGet() == 0) {
db.beginTransaction();
try {
for (Runnable r : mRunnables) r.run();
db.setTransactionSuccessful()
} finally {
db.endTransaction();
}
}
}
}
當您創建的每個工作,你通過這個共享DbBundle,最後一個會全部執行它們。 因此,一份工作看起來像:
....
try {
if (!dbBundle.isCanceled()) { // avoid extra request if it is already canceled
final List<User> users = webservice.getUsers();
dbBundle.submit(new Runnable() {
void onRun() {
saveUsers(users);//which calls db. no transaction code.
});
});
} catch(Throwable t) {
dbBundle.cancel();
}
謝謝,我認爲這可能是要走的路。雖然我不太瞭解你對有關工作不同步的評論。我也許沒有提到每項工作本質上都是將寫入數據寫入不同的表中,除了所有這些工作都應該順利完成以成功完成同步之外,這些工作之間不存在依賴關係。如果作業B失敗,我會期望中止該過程並結束交易失敗。順便說一句,我使用的Android優先級作業隊列,我認爲你開發:) – jdmunro 2014-10-07 08:34:06
哈,是的,這看起來像一個問題引起的解耦的東西:)。 你提到JobA和JobB應該都完成或者都失敗。即使使用數據庫事務(如果他們正在工作),您也需要阻止JobA直到JobB完成,這對Job線程沒有很好的使用(並且如果依賴作業數量大於最大消費者數量,將會死鎖)。也許我們可以將它作爲JobManager的擴展。我一直在想這些有用的擴展工作。如果你碰巧寫了一個通用的請求,隨意發送一個拉取請求。 – yigit 2014-10-08 04:08:12
我仍然不確定是否需要阻止JobA(我認爲我誤解了某些東西!)。讓我們說JobA下載一些實體並將它們插入到數據庫中。與JobB中下載的數據沒有任何關係。同時,JobB下載它的實體並將它們插入到數據庫中。 AFAIK,greenDAO確保對數據庫的串行訪問。因此,讓我們說我們確實有一些方便的方法將所有這些封裝到整個事務中。如果JobA失敗,我們將中止這個整體交易,並取消JobB。這不會確保DB數據的原子性,而無需同步作業? – jdmunro 2014-10-08 11:09:43