在数据库开发中,事务处理是非常重要的。
首先Android数据库操作(特别是写操作)是非常慢的,将所有操作打包成一个事务能大大提高处理速度。
其次是保证数据的一致性,一个事务中的所有操作可以看作一个原子操作,成功或者失败。如果全部成功,则事务提交完成;而事务内部如果有失败操作,整个事务操作会回滚,从而保证数据的一致性。
Android中事务的调用:
try {
db.beginTransaction();
//在这里执行多个数据库操作
//执行过程中可能会抛出异常
db.setTransactionSuccessful();
//在setTransactionSuccessful和endTransaction之间不进行任何数据库操作
} catch (Exception e){
} finally {
//当所有操作执行完成后结束一个事务
db.endTransaction();
}
有2点需要注意的是:
- 一定要调用
db.setTransactionSuccessful();
事务才会成功提交完成 - 事务是可以嵌套的
以上2点也是自己开发中犯错了才觉察到的:没有调用db.setTransactionSuccessful();
发现数据没有插入;想当然的认为事务不可以嵌套。而Android的源码中也很清楚的说明了这2点,所以究其根本原因是对事务处理不够熟悉,对Android中事务的处理不熟悉。在此记录警示自己!
以下贴出Android中相关连的源代码,来自android.database.sqlite.SQLiteDatabase:
/**
* Begins a transaction in EXCLUSIVE mode.
* <p>
* Transactions can be nested.
* When the outer transaction is ended all of
* the work done in that transaction and all of the nested transactions will be committed or
* rolled back. The changes will be rolled back if any transaction is ended without being
* marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.
* </p>
* <p>Here is the standard idiom for transactions:
*
* <pre>
* db.beginTransaction();
* try {
* ...
* db.setTransactionSuccessful();
* } finally {
* db.endTransaction();
* }
* </pre>
*/
public void beginTransaction() {
beginTransaction(null /* transactionStatusCallback */, true);
}
注释中说明的很清楚:事务可以嵌套,事务标记为成功才会提交,否则直接回滚。