一、事务的四大特性(关联记忆: .原子性 |一致性 ○隔离性 --持久性)
原子性(.)
原子性:指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
一致性(|)
一致性:事务开始前和结束后,数据库的完整性约束没有被破坏。比如A向B转账,不可能A扣了钱,B却没收到。
隔离性(○)
隔离性:是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
持久性(--)
持久性:指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
二、事务的并发问题有三个
1.脏读: 事务A读取事务B,B事务回滚 A读取到的是B回滚前(更新后但是尚未提交的数据)数据。A读的这一部分就是脏数据,这个结果脏读。
2.不可重复读:事务A首先读取事务B第一次更新的数据(B1),B再次更新并提交后,事务A再次读取B第二次更新的数据(B2)。B1!=B2,这就是不可重复读。
3.幻读:同一事务中,用同样的操作读取两次,得到的记录数不相同。
三、解决方法
( mvcc 和 锁 都可以解决幻读、重复读问题。两者方式不一样,前者通过冗余数据,后者通过锁。)
脏读:
1.修改时加排它锁,事务提交后释放(修改时加排他锁,修改过程中不允许其他事务修改,修改完成后释放锁)。
2.读取时加共享锁,读取完后释放共享锁(读取时增加共享锁,读取过程中只允许读,不允许修改)1和2结合就能防止脏读问题。
注意:但是当事务1读取数据过程中,有可能事务2也读取了该数据,读取完毕后共享锁释放,紧接着事务1修改数据,修改完毕提交事务(先释放锁在提交事务)。事务2再次读取数据时候发现数据不一致,就会出现不可重复读问题,所以这样不能够避免不可重复读问题。
不可重复读:读取数据时加共享锁,写数据时加排他锁,都是事务提交才释放锁(先提交事务在放锁,-》对比上面蓝色部分内容,注意事务和锁的前后顺序)。读取时候不允许其他事物修改该数据(锁行),不管数据在事务过程中读取多少次,数据都是一致的,避免了不可重复读问题。
3.幻读:锁表
四、为了解决脏读、不可重复读、幻读,事务分成五种隔离级别:
1.TRANSACTION_NONE 不使用事务。
2.TRANSACTION_READ_UNCOMMITTED 允许脏读。
3.TRANSACTION_READ_COMMITTED 防止脏读,最常用的隔离级别,并且是大多数数
据库的默认隔离级别
4.TRANSACTION_REPEATABLE_READ 可以防止脏读和不可重复读,
5.TRANSACTION_SERIALIZABLE 可以防止脏读,不可重复读取和幻读,(事务串行
化)会降低数据库的效率
(以上是自己理解加上参照别人的例子,有错希望大家提出来! o(╯□╰)o)