Fork me on GitHub

数据库事务的四大特性和隔离级别

事务的四大特性(ACID)

事务是由一组SQL语句组成的逻辑处理单元,事务具有以下四个属性,通常简称为事务的ACID属性。

  • 原子性(Atomicity): 事务是一个原子操作单元,其堆数据的修改,要么全都执行,要么全都不执行。
  • 一致性(Consistency): 一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
  • 隔离性(Isolation): 隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
    即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
  • 持久性(Durability): 事务一旦被提交,它对于数据的修改是永久性的,即时出现系统故障也能够保持。

并发带来的问题

当多个线程都开启事务操作数据库时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,如果不考虑事务的隔离性,会发生以下几种问题:

  • 丢失更新:当多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他十五的存在,就会发生丢失更新问题—最后的更新覆盖了有其他事务所做的更新。
  • 脏读: 事务A读取到了事务B已修改但尚未提交的数据。
  • 不可重复读: 事务A读取到了事务B已经提交的修改数据,不符合隔离性。
  • 幻读: 事务A读取到了事务B提交的新增数据,不符合隔离性。
    脏读和幻读区别: 脏读是事务B里面修改了数据,幻读是事务B新增了数据

事务隔离级别

“脏读”、”不可重复读”,”幻读”其实都是数据库读一致性问题,必须由数据库提供一定的事务隔离机制来解决。
读数据一致性及允许的并发副作用:

隔离级别 读数据一致性 脏读 不可重复读 幻读
读未提交(Read uncommitted) 最低级别,只能保证不读取物理上损坏的数据
读已提交(Read committed) 语句级别
可重复读(Repeatable read) 事务级别
串行化(Serializable) 最高级别

数据库事务级别越高,并发副作用越小,但付出的代价也就越大。像Serializable这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。在MySQL数据库中默认的隔离级别为Repeatable read (可重复读)。

隔离级别的查看与设置

查看: select @@tx_isolation;
设置: set [glogal | session] transaction isolation level 隔离级别名称;或者set tx_isolation=’隔离级别名称;’
设置数据库的隔离级别一定要是在开启事务之前!隔离级别的设置只对当前链接有效。对于使用MySQL命令窗口而言,一个窗口就相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于JDBC操作数据库来说,一个Connection对象相当于一个链接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关。

-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!