MySQL事务详解
1,MySQL事务
MySQL的特性
原子性( Atomicity):事务的所有操作要么全部成功,要么全部回滚。 一致性( Consistency):总是从一个一致性的状态转换到另一个一致性的状态。 隔离性( Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行 持久性( Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。
MySQL隔离级别
| 隔离级别 | 脏读(Dirty Read) | 不可重复读(NonRepeatable Read) | 幻读(Phantom Read) |
|---|---|---|---|
| 读未提交(Read uncommitted) | 可能 | 可能 | 可能 |
| 读已提交(Read committed) | 不可能 | 可能 | 可能 |
| 可重复读(Repeatable read) | 不可能 | 不可能 | 可能 |
| 可串行化(Serializable ) | 不可能 | 不可能 | 不可能 |
InnoDB默认是可重复读级别的
Oracle默认是读已提交
-
① 脏读: 脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
-
② 不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
-
③ 幻读:第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样,幻读是数据行记录变多了或者少了。
简单点总结下他们的区别:脏读是指读取了未修改完的记录,不可重复读指因为被其它事务修改了记录导致某事务两次读取记录不一致,而幻读是指因为其它事务对表做了增删导致某事务两次读取的表记录数不一致问题。
解决办法(四种隔离级别)
1、Read Uncommited(读取未提交内容)
读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。但是,读未提交产生了脏读,采用读提交可以解决脏读问题
2、Read Commited(读取提交内容)
读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。读提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。但在这个事例中,出现了一个事务范围内两个相同的查询却返回了不同数据,这就是不可重复读。但是,读提交两次查询会产生不同的查询结果,就会造成不可重复读问题,采用重复读可以解决此问题。
3、Repeatable Read(重复读)
重复读,就是在开始读取数据(事务开启)时,不再允许修改操作。重复读可以解决不可重复读问题。应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。采用Serializable可以解决幻读问题
4、Serializable(可串行化)
Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
【注意】
1、大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。Mysql的默认隔离级别是Repeatable read。
2、隔离级别的设置只对当前链接有效。对于使用MySQL命令窗口而言,一个窗口就相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于JDBC操作数据库来说,一个Connection对象相当于一个链接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关。
3、设置数据库的隔离级别一定要是在开启事务之前。
总结
读已提交解决脏读,
可重复读解决脏读、不可重复读,
浙公网安备 33010602011771号