1.1 并发访问概述
一个数据库可能拥有多个访问客户端,这些客户端都可以并发方式访问数据库,数据库的相同数据可能被多个事务同时访问,如果不采取隔离措施,就会导致各种问题, 破坏数据的完整性。
事务在操作时的理想状态: 所有的事务之间保持隔离,互不影响。因为并发操作,多个用户同时访问 同一个 数据。可能引发并发访问的问题
1.2 并发访问的问题 :
1、脏读: 一个事务读取到了另一个事务中尚未提交的数据。
2、不可重复读: 同一个事务中,进行查询操作,但是每次读取的数据内容都不一样。
3、幻读: select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在, 无法插入,此时就发生了幻读。
2.1 查看隔离级别
select @@tx_isolation
2.2 设置事务隔离级别
set global transaction isolation level 级别名称;
read uncommitted 读未提交 (1,2,3) -- ()中的数字代表能发生的问题 1代表脏读,2代表不可重复读,3代表幻读。
read committed 读已提交 (X,2,3)
repeatable read 可重复读 (X,X,3)
serializable 串行化 (X,X,X) -- 最安全,但是效率最低
2.3 隔离性问题解决方案
2.3.1 解决脏读问题
脏读非常危险的,比如张三向李四购买商品,张三开启事务,向李四账号转入500 块,然后打电 话给李四说钱已经转了。李四一查询钱到账了,发货给张三。张三收到货后回滚事务,李四的再查看钱没了。
解决方案 : 将全局的隔离级别进行提升为: read committed
2.3.2 解决不可重复读问题
比如银行程序需要将查询结果分别输出到电脑屏幕和发短信给客 户,结果在一个事务中针对不同的输出目的地进行的两次查询不一致,导致文件和屏幕中的结果不一致,银行工作人员就不知道以哪个为准。
解决方案 : 将全局的隔离级别进行提升为:repeatable read
2.3.3 解决幻读问题
如果一个事务,使用了SERIALIZABLE——可串行化隔离级别时,在这个事务没有被提交之前 , 其他的线程,只能等到当前操作完成之后,才能进行操作,这样会非常耗时,而且影响数据库的性能,数据库不会使用这种隔离级别。
解决方案 : 将事务隔离级别提升为:SERIALIZABLE ,防止幻读的发生。