数据库事务的四大特性
总结起来就是: ACID
- A–>Automic, 原子性,指的是事务包含的所有操作,
要么全部执行
,要么全部失败回滚
. - C–>Consistency.一致性,指的是事务应确保数据库的状态从一个一致性的状态,转变为另外一个一致的状态, 而
一致状态
是指数据库中的数据应满足完整性约束,比如说两个用户互相转账,他俩不管怎么转,钱的总数都应该是相等的. - I–>Isolation,隔离性,指的是多个事务并发执行时,一个事务的执行不应该影响其他事务的执行.
- D–>Durability,持久性,指的是一个事务一旦提交或者更新,它对数据库的修改应该永久地保存在数据库中,
这也就意味着当系统或者介质发生故障时,要确保已提交事务的更新不能丢失,即对已提交事务的更新可以恢复,一旦一个事务已经提交,DBMS必须保证提供适当的冗余使其耐得住系统故障
,所以,持久性主要在于DBMS的恢复性能,**例如:**InnoDB就会把所有对页面的修改操作写入一个专门的文件,并在数据库启动时,从此文件(redo log files)
进行恢复操作.
事务并发引起的问题
- 更新丢失:指的是一个事务的更新覆盖了另一个事务的更新,mysql中的所有事务隔离级别在数据库层面均可避免这个问题(因为都加了锁).
- 脏读问题: 指的是一个事务读到另一个事务未提交的更新数据,例如事务A对某行数据进行了更新,但是没有提交,此时事务B查询该行数据,便会查询到该行已更新后的数据,此时如果事务B拿着这个数据去执行更新操作,但是要是事务A没提交而是回滚了的话,数据就乱了, 这种问题可以在
READ-COMMITTED(读-已提交)
隔离级别及以上可以避免.
查看事务隔离级别语句: select @@tx_isloation 但是在mysql8.0以上是: SELECT @@transaction_isolation
修改事务隔离级别: set session transaction isolation level + 隔离级别
- 不可重复读问题:指的是事务A多次读取同一数据,事务B在事务A多次读取的过程中,对数据进行了更新并提交,导致事务A多次读取同一数据时结果不一致(事务A一脸懵逼,我啥都没做啊),要是事务B给更新了数据但是事务A不晓得,然后事务A用原来的数据去做更新操作,就会出问题.,这个问题在
REPEATEABLE-READ(可重复读,InnoDB默认)
事务隔离级别以上可避免(事务A虽然查询的是原来的数据,但是实际上更新时用的是事务B更新后的数据,数据库会记录下事务B的更新操作,事务级别在可重复读以下的数据库不会将实际数据用于事务A的更新操作,谁后提交就保存谁的更新结果,这样就会出问题
). - 幻读问题:指的是事务A先读取与搜索条件相关的若干行,然后事务B以向数据库中插入或者删除行等方式执行了更新语句,此时修改了事务A的查询的结果集但是事务A由于没有重新执行查询语句所以不知道,此时如果事务A对数据库执行更新操作,会发现被操作的行的数量和之前查出来的不一样,导致事务A看起来像出现幻觉一样,搞不清楚我这里到底有哪些行, 这个问题在
SERIALIZABLE(串行xing化)
隔离级别(最高隔离级别)可避免(当事务A查询时,它会给该行加上共享锁,在事务B中加排它锁只能等事务A提交或回滚释放锁之后).
总结(从上往下隔离级别从低到高):