Home

概念

所谓事务,它是一个操作集合,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。

特性

  1. 原子性(Atomicity)
    当事务结束,它对所有资源状态的改变都被视为一个操作,这些操作要不同时成功,要不同时失败, undo记录了数据在事务开始之前的值,当事务执行失败或者ROLLBACK时可以通过undo记录的值来恢复数据。
  2. 一致性(Consistency)
    一个事务执行之前和执行之后都必须处于一致性状态。 拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。
  3. 隔离性(Isolation)
    事务以相互隔离的方式执行,事务以外的实体无法知道事务过程中的中间状态,加锁实现。
  4. 持久性(Durable)
    那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。引入redo日志记录数据修改后的值,可以避免数据在事务提交之前必须写入到磁盘的需求,减少I/O。

如果不考虑事务的隔离性,会发生的几种问题、以及解决方法:

1.数据丢失:数据发生数据覆盖,两个线程同时对同一个数据进行写操作,会发生数据的覆盖。 后修改的数据覆盖前一次的修改。解决方法:对同一个数据的写操作加上排它锁,要写数据了, 就把它用X锁锁住, 锁住后,除非你释放, 否则别人无法获得X锁

2.脏读:读到没提交的数据,一个线程在写操作的时候,另一个线程进来读读完立即释放。读到脏数据。解决方法:对同一个数据加共享锁,读和写、写和读、写和写不能共存,读和读可以共存。约定一下, 读一个数据之前加S锁, 读完之后立刻释放该S锁 ! ”

3.不可重复读:两次读的数据不一致,解决方法:我们之前的约定是读数据时加S锁, 读完立马释放,问题就出现在这里了,看来在读数据的时候, 也需要一直锁定了, 直到事务提交

4.幻读:两次读的数据的量不一致, 和不可重复读很类似,不过修改数据改成增加数据。

解决方法:串行化
现在来看看MySQL数据库为我们提供的四种隔离级别:

① Serializable (串行化):
可避免脏读、不可重复读、幻读的发生。
② Repeatable read (可重复读):
可避免脏读、不可重复读的发生。:
③ Read committed (读已提交)::
可避免脏读的发生。:
④ Read uncommitted (读未提交)::
最低级别,可避免数据丢失。