事务:指的一组操作,里面有许多单一的逻辑。只要有一个逻辑没有执行成功,就算失败。所有的数据都回归到最初的状态(rollback)

  • 为什么要有事务

为了确保逻辑的成功

  • 开启事务 start transaction
  • 提交或回滚事务 commit:提交事务,数据会写到磁盘上的数据库中 rollback:数据回滚,回到最初始状态

事务的特性(ACID)

  • 原子性

指的是 事务中包含的逻辑,不可分割

  • 一致性

指的是 事务执行前后。数据完整性

  • 隔离性

指的是 事务执行期间不应该受到其他事务的影响

  • 持久性

指的是 事务执行成功后,数据应该保存到磁盘上

事务的隔离级别

读未提交

引发问题:脏读

读已提交

解决:脏读 引发:不可重复读

可重复读

解决:脏读,不可重复读 未解决:幻读

可串行化

解决:脏读,不可重复读,幻读

mysql的默认隔离级别:可重复读

Oracle的默认隔离级别:读已提交

事务的安全隐患

不考虑隔离级别(读未提交,读已提交,可重复读,可串行化)设置,那么会出现以下问题

    • 脏读:一个事务读到另外一个事务还未提交的数据
      • 设置A窗口的隔离级别 *读未提交
      • 两个窗口都分别开启事务
      • A窗口修改数据还没提交,B窗口select数据就是脏数据(不正确的)
    • 不可重复读 :只能读取到其他事务已经提交的数据,哪些没有提交的数据是读不出来的。会造成前后读取的结果不一样。不可重复读指的是不能执行多次读取,否则会出现结果不一。
      • 设置A窗口的隔离级别为 读已提交
      • AB两窗口都开启事务,在B窗口执行更新操作
      • 在A窗口两次查询数据不相同,一次是在B窗口提交事务之前,一次是在B窗口提交事务之后
      • 这个隔离级别能够屏蔽脏读现象,但是引发了另一种现象,不可重复读
    • 幻读:一个事务读到另外一个事务insert的数据
      • 如果有一个连接的隔离级别设置为了可串行化。那么谁先打开了事务,谁就有了先执行的权利。谁后打开了事务,就必须等待前面的事务提交或者回滚后,才能执行。但是这种级别比较少用,因为会造成性能上的问题。效率比较低
    • 丢失更新

      • B事务如果提交,那么会造成修改的姓名没有了
      • B事务回滚,那么会造成A想更新的数据没有。因为B记得自己拿出来的数据是lisi 1000
    • 解决方案,锁机制

      • 悲观锁:select * from account for update。只要当A的更新提交了,B才能再一次查看数据,未提交查看界面卡住。

      • 乐观锁。A事务先提交,数据库version变为1;B在提交的时候比对数据库version,不一样则不允许提交,要先更新。