こんばんわ。
同じ事で悩んでいたのですが、一つの解決策を見つけました。
SQLiteはtransactionを利用するのとしないのとでは、数十件程度の更新でも処理時間に大きな違いが出るので、複数件のデータを扱うなら
是非利用したいです。
どうしてContentProviderにtransactionを扱う機能が無いのか不思議なのですが、無理矢理実装すれば使えなくもなさそうで
す。
ContentProviderの各処理は、受け取ったUriによって更新させるテーブルを分岐させていると思いますが、insert()に
transactionの開始とcommitとrollbackを行う分岐を追加してやります。下の2,3,4がそれです。
static{
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI("com.test.provider", "insert", 1);
sUriMatcher.addURI("com.test.provider", "transaction", 2);
sUriMatcher.addURI("com.test.provider", "commit", 3);
sUriMatcher.addURI("com.test.provider", "rollback", 4);
}
@Override
public Uri insert(Uri arg0, ContentValues arg1) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
switch (sUriMatcher.match(arg0)) {
case 1:
db.insert("test", null, arg1);
break;
case 2:
db.beginTransaction();
break;
case 3:
db.setTransactionSuccessful();
db.endTransaction();
break;
case 4:
db.endTransaction();
break;
}
return null;
}
そして、ContentProviderを使用する際は、最初にbeginTransaction()を実行するUriを発行してやり、更新処理を行っ
た後、commitかrollbackを実行するUriを発行します。
//transaction開始
getContentResolver().insert(Uri.parse("content://com.test.provider/
transaction"),null);
//色んな処理
getContentResolver().update(~~~)
getContentResolver().delete(~~~)
getContentResolver().insert(~~~)
//commit
getContentResolver().insert(Uri.parse("content://com.test.provider/
commit"),null);
色々試してみましたが、期待通りの動きをしてくれます。途中で失敗すればrollbackされますし、登録、更新、削除が入り乱れていても高速に処理出
来ます。
本当に無理矢理ですけど、いかがでしょうか。
On 10月10日, 午前3:02, あわ <
awwa...@gmail.com> wrote:
> あわと申します。
>
> AndroidのContentProviderを使っていて、疑問に思ったので質問です。
>
> ContentProviderを使って、複数テーブルに対して複数レコードの更新を行う場合、
> トランザクションを利用してエラーが発生した際にデータの不整合が
> 起きないようにロールバックをさせようと思ったのですが、
> 参考になるやり方が見つかりませんでした。
>
> ContentProviderのリファレンスを見ると、
> If you don't need to share data amongst multiple applications you can use a
> database directly
> viaSQLiteDatabase<file:///C:/android-sdk-windows-1.6_r1/docs/reference/andr oid/database/sqlite/SQLiteDatabase.html>
> .
> とあり、単に自アプリ内でのデータの更新にはSQLiteDatabaseを直接扱ってね、的なことが書いてあります。
> 確かに、それはそれでトランザクションの機能が利用できるし、理解できるのですが、
> 他のアプリケーションがContentProvider経由でデータの操作を許可している場合、
> トランザクション機能を利用したいケースについてはどうやって実装すればよいのでしょうか?
>
> そもそもこんな疑問を持つこと自体ナンセンスなのでしょうか?
> どうぞよろしくお願いいたします。
>
> --
>
awwa...@gmail.com