数据库中的事务

什么是事务

在和数据库打交道的时候,多少会接触到事务这个词,事务确实解决了很多问题呢!
简单说:就是把多件事情当做一件事情来处理。也就是大家同在一条船上,要活一起活,要完蛋都完蛋 !

数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。

更新:2017-5-2 完善相关概念

事务特点(ACID)

可以这么说,如果数据库支持 ACID ,那么就支持事务;如果说它支持事务,那就一定支持 ACID

  • 原子性(Atomicity)
    事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行;就是说不可分割
  • 一致性(Consistency)
    事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态 的含义是数据库中的数据应满足完整性约束
    简单说就是:前后数据的完整性保持一致( 这个+10 那个就要 -10,总数不变 )
  • 隔离性(Isolation)
    多个事务并发执行时,一个事务的执行不应影响其他事务的执行
  • 持久性(Durability)
    已被提交的事务对数据库的修改应该永久保存在数据库中
    即使接下来数据库炸了也要把之前事务的影响保存好,这是数据库该操心的事

通俗点的理解就是:
原子性:记录之前的版本,允许回滚
一致性:事务开始和结束之间的中间状态不会被其他事务看到
隔离性:适当的破坏一致性来提升性能与并行度 例如:最终一致~=读未提交。
持久性:每一次的事务提交后就会保证不会丢失

隔离性

主要说下这个隔离性,先来明确如果不考虑隔离性的话会造成的后果:

  • 脏读
    读取到别人未提交的事务对表的影响
    比如 A、B 两个连接同时开启了一个事务;A 事务查询表的时候 B 事务更新了数据,但是没有提交,在 A 中却能查到更新后的结果
  • 不可重复读
    两次查询结果不同,第一次和第二次之间别人(连接)进行了事务提交
    同上的例子,只不过是 B 更新表、提交事务后,在 A 的事务中(A 事务还未完成)能查到 B 提交后的结果;这就是两次相同查询不一样的结果,不可重复读
  • 虚读(幻读)
    和不可重复读类似,只不过这次的事务提交是对表的操作,比如插入、删除一条记录

隔离级别

然后就可以说说隔离级别了,是为了解决上面的问题

  • Serializable
    可避免上面的全部问题,同时效率也是最低的 (串行化)
    有点类似单线程操作,如果 A 在处理事务,在未完成之前,其他连接只能等着
  • Repeatable read
    可避免 脏读、不可重复读 (可重复读) [mysql 默认]
  • Read committed
    可避免脏读 (读已提交) [oracle 默认]
  • Read uncommitted
    最低级别,3 种问题均无法保证 (读未提交)

oracle 数据库只支持 1 和 3 ;MySQL 是全支持的

在Android中

使用事务的优点

  • 在 Android 应用程序开发中,经常会遇到需要进行数据库操作的时候,Android 中数据库操作(尤其是写操作)是非常慢的,打包成事务有利于提高效率。
  • 保证数据的一致性,有关事务的操作全部成功后才提交(生效),否则就进行事务的回滚操作。

事务的使用(SQLite示例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void payment()
{
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
//开启事务
db.beginTransaction();
try
{
db.execSQL("update person set amount=amount-10 where personid=?", new Object[]{1});
db.execSQL("update person set amount=amount+10 where personid=?", new Object[]{2});
//设置事务标志为成功,当结束事务时就会提交事务
db.setTransactionSuccessful();
}
catch(Exception e){
throw(e);
}
finally
{
//结束事务
db.endTransaction();
}
}

当然 JDBC 的文章中也有提及,只要涉及数据库操作,基本都有支持

补充

事务是可以嵌套的,Android官方源码解释:

* 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.

个人理解:一般数据的操作用到事务,从而保证数据的准确一致,操作全部完成后再提交,只有提交后才会生效。

其他参考

Fragment的事务解析

待添加…

喜欢就请我吃包辣条吧!

评论框加载失败,无法访问 Disqus

你可能需要魔法上网~~