摘要:事务
什么是事务
事务是一系列的操作,他们要符合ACID特性.常见的理解就是:事务中的操作要么全部成功,要么全部失败.
ACID
A=Atomicity 原子性
就是上面说的,要么全部成功,要么全部失败.不可能只执行一部分操作.C=Consistency 一致性
系统(数据库)总是从一个一致性的状态转移到另一个一致性的状态,不会存在中间状态.I=Isolation 隔离性
通常来说:一个事务在完全提交之前,对其他事务是不可见的.注意前面的通常来说加了红色,意味着有例外情况.D=Durability 持久性
一旦事务提交,那么就永远是这样子了,哪怕系统崩溃也不会影响到这个事务的结果.
MYSQL支持事务吗?
5.5之前 是 myISAM
在缺省模式下,MYSQL是autocommit模式的,所有的数据库更新操作都会即时提交,所以在缺省情况下,mysql是不支持事务的。
但是如果你的MYSQL表类型是使用InnoDB Tables 或 BDB tables的话,你的MYSQL就可以使用事务处理,使用SET
AUTOCOMMIT=0就可以使MYSQL允许在非autocommit模式,在非autocommit模式下,你必须使用COMMIT来提交你的更改,或者用ROLLBACK来回滚你的更改。
5.5之后是InnoDB,支持事务
同时有多个事务在进行会怎么样呢?
多事务的并发进行一般会造成以下几个问题:
- 脏读: A事务读取到了B事务未提交的内容,而B事务后面进行了回滚.
- 不可重复读: 当设置A事务只能读取B事务已经提交的部分,会造成在A事务内的两次查询,结果竟然不一样,因为在此期间B事务进行了提交操作.
- 幻读: A事务读取了一个范围的内容,而同时B事务在此期间插入了一条数据.造成”幻觉”.
MySQL的四种隔离级别
- 未提交读(READ UNCOMMITTED) 读到未提交数据
这就是上面所说的例外情况了,这个隔离级别下,其他事务可以看到本事务没有提交的部分修改.因此会造成脏读的问题(读取到了其他事务未提交的部分,而之后该事务进行了回滚).
这个级别的性能没有足够大的优势,但是又有很多的问题,因此很少使用.
- 已提交读(READ COMMITTED) 脏读,不可重复读
其他事务只能读取到本事务已经提交的部分.这个隔离级别有 不可重复读的问题,在同一个事务内的两次读取,拿到的结果竟然不一样,因为另外一个事务对数据进行了修改.
- REPEATABLE READ(可重复读)(InnoDB默认使用)
可重复读隔离级别解决了上面不可重复读的问题,但是仍然有一个新问题,就是 幻读,当你读取id> 10 的数据行时,对涉及到的所有行加上了读锁,此时例外一个事务新插入了一条id=11的数据,因为是新插入的,所以不会触发上面的锁的排斥,那么进行本事务进行下一次的查询时会发现有一条id=11的数据,而上次的查询操作并没有获取到,再进行插入就会有主键冲突的问题.
- SERIALIZABLE(可串行化事务)
这是最高的隔离级别,可以解决上面提到的所有问题,因为他强制将所以的操作串行执行,这会导致并发性能极速下降,因此也不是很常用.
mysql 锁
当数据库有并发事务的时候,可能会产生数据的不一致,这时候需要一些机制来保证访问的次序,锁机制就是这样的一个机制.
例如,酒店的房间,如果大家随意进出,就会出现多人抢夺同一个房间的情况,而在房间上装上锁,申请到钥匙的人才可以入住并且将房间锁起来,其他人只有等他使用完毕才可以再次使用.
MySQL都有哪些锁?
从锁的类别上来讲,有共享锁和排他锁.
共享锁: 又叫做读锁. 当用户要进行数据的读取时,对数据加上共享锁.共享锁可以同时加上多个.
排他锁: 又叫做写锁. 当用户要进行数据的写入时,对数据加上排他锁.排他锁只可以加一个,他和其他的排他锁,共享锁都相斥.
锁的粒度
锁的粒度取决于具体的存储引擎,InnoDB实现了行级锁,页级锁,表级锁.
- 表锁,系统开销最小,会锁定整张表,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。MyIsam使用表锁。
- 行锁,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。InnoDB使用行锁。
- 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
他们的加锁开销从大到小,并发能力也是从大到小.
锁作用
加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。