数据库事务、特性以及隔离级别

来源:互联网 发布:pe系统网络组件下载 编辑:程序博客网 时间:2024/05/16 16:04

数据库的事务

  1. 事务的基本概念

    所谓事务,是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分隔的工作单位。
    事务通常以bigin transaction开始,以commit或rollback结束。commit表示提交开启事务后的所有操作,即将事务中的所有对数据库的更新操作写回到物理磁盘中去,事务正常结束。rollback表示回滚,即在事务过程中发生了某些错误或故障,事务不能继续执行,而将事务中所有已完成的操作撤销,回到事务之前的状态。
    事务是恢复和并发控制的基本单位。
  2. 事务的四个特性(ACID)

    1. 原子性
    事务是数据库的逻辑工作单位,事务中包括的操作要么全做要么全不做。
    1. 一致性
    事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。比如:a和b两个银行账号,现在某人从a从取出10000,存入b账号,这两步应该属于一个事务,要么全做,要么全不做,假设只做了第一步,那么这时就会莫名少了10000元,这时数据库就处于不一致状态。
    1. 隔离性
    一个事务的执行不能被其它事务干扰,即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
    1. 持久性
    指一个事务一旦提交,它对数据库中数据的改变就是永久性的。
  3. 并发操作可能带来的问题

    1. 脏读
    脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。   当一个事务正在修改某个数据,而在这个事务中未提交时,另一个事务来访问该数据,读取到的是前一个事务修改的值,而这时第一个事务恢复了其值,此时第二个事务读的数据就是脏数据。
    1. 不可重复读
    不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
    例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。
    1. 幻读
    事务T1按一定条件从数据库读取了某些数据记录后,此时事务T2插入(或删除)了一条记录,并提交了事务,而此时T1按相同条件再次读取时会发现记录多了(少了)一条,这种现象叫幻读。 (有些还会写一种叫丢失修改的现象,即T1和T2同时读入同一个数据并修改,T2提交的结果破坏了T2提交的结果,导致T1丢失了修改。)
  4. mysql的事务级别

    Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
    Repeatable read (可重复读):可避免脏读、不可重复读的发生。
    Read committed (读已提交):可避免脏读的发生。
    Read uncommitted (读未提交):最低级别,任何情况都无法保证。

以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,当然级别越高,执行效率就越低。像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。在MySQL数据库中默认的隔离级别为Repeatable read (可重复读)。

在MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read (可重复读);而在Oracle数据库中,只支持Serializable (串行化)级别和Read committed (读已提交)这两种级别,其中默认的为Read committed级别。

  1. spring事务隔离级别

    PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
    PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
    PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
    PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
    PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
0 0