MySQL_事务_并发问题
对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题:
详细:
· 脏读:对于两个事务T1,T2,T1读取了已经被T2更新但还没有提交的字段之后,若T2回滚,T1读取的内容就是临时且无效的
· 不可重复读:对于两个事务T1,T2,T1读取了以恶搞字段,然后T2更新了该字段之后,T1再次读取同一个字段,值就不同了
· 幻读:对于两个事务T1,T2,T1从一个表中读取了一个字段,然后T2在该表中插入了一些新的行之后,如果T1再次读取同一个表,就会多出几行
简略:
脏读(更新但没有被提交时):如果撤销,则之前的操作无效
不可重复读(更新):结果不一样
幻读(插入时):多出几行
避免
数据库的隔离级别
Read uncommitted读未提交数据:
(允许事务读取违背其他事务提交的变更,脏读,不可重复读和幻读的问题都会出现)
一个事务可以读取另一个未提交事务的数据。
问题:会出现脏读
解决:读提交
Read committed读已提交数据:
(只允许事务读取已经被其他事务提交的变更,可以避免脏读,但不可重复读和幻读问题仍然可能出现)
一个事务要等另一个事务提交后才能读取数据。
问题:一个事务范围内两个相同的查询却返回了不同数据,这就是不可重复读。
解决:重复读
Repeatable read可重复读:
(确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,机制其他事物对这个字段进行更新,可以避免脏读和不可重复读,但幻读的问题仍然存在)
就是在开始读取数据(事务开启)时,不再允许修改操作
不可重复读对应的是修改,即UPDATE操作
问题:幻读(幻读问题对应的是插入INSERT操作)
解决:Serializable
Serializable序列化:
(确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事物对该表执行插入,更新和删除操作,所有并发问题都可以避免,但性能低下)
最高的事务隔离级别,在该级别下,事务串行化顺序执行
大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。
Mysql的默认隔离级别是Repeatable read。
脏读 | 不可重复读 | 幻读 | |
read uncommitted读未提交 | √ | √ | √ |
read committed读已提交 | × | √ | √ |
repeatable read重复读 | × | × | √ |
serializable序列化 | × | × | × |
MySQL中默认第三个隔离级别 repeatable read重复读
Oracle中默认第二个隔离级别 read committed读已提交
查看隔离级别
SELECT @@tx_isolation;
设置隔离级别
SET SESSION | GLOBAL TRANSACTION isolation level 隔离级别;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了