前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试官:你连MySQL事务都不会用?老程序员教你4招事务锁魂神技

面试官:你连MySQL事务都不会用?老程序员教你4招事务锁魂神技

原创
作者头像
司夜
发布2023-08-04 17:27:01
1660
发布2023-08-04 17:27:01
举报
文章被收录于专栏:开发三两事开发三两事

最近我面试一个应届生,询问他关于MySQL事务的了解。那小伙子支支吾吾半天,竟说从来没用过事务!我简直不敢相信自己的耳朵——作为一个Java程序员,这也太 basics 了吧?

不过转念一想,我又意识到许多老程序员也存在这个问题,即使项目中用了事务,也仅仅停留在会用的层面,并没有深入理解其中的原理。为了帮助大家避免面试中的尴尬,今天我就来讲讲MySQL事务的实用技巧,也算为这个行业添砖加瓦吧!

MySQL事务工作原理剖析

废话不多说,让我们直接深入MySQL事务的工作原理。这里我用通俗易懂的语言,给大家快速科普一下:

  • 事务的基本操作
    • BEGINCOMMIT语句来启动和提交一个事务
    • ROLLBACK可以中止事务,回退所有修改
  • 事务的ACID原则
    • 原子性(Atomicity)
    • 一致性(Consistency)
    • 隔离性(Isolation)
    • 持久性(Durability)
  • 并发控制
    • MVCC多版本并发控制可以实现事务的隔离性,避免脏读、幻读等问题
  • Undo日志和Redo日志
    • Undo日志用于事务回滚
    • Redo日志用于确保事务持久化

这些基本概念必须牢记,才能更好地运用事务。今天我重点来讲讲几个实用技巧。

事务的隔离级别选择

MySQL提供了4种隔离级别来控制事务并发时的隔离性。我们该如何选择合适的隔离级别呢?

隔离级别

说明

读未提交(Read uncommitted)

最低级别,可以读取脏数据

读提交(Read committed)

可以避免脏读,但不可重复读和幻读可能发生

可重复读(Repeatable read)

在同一事务内多次读取结果一致,但可能幻读

串行化(Serializable)

最高级别,可以防止脏读、不可重复读和幻读

一般来说,可重复读级别能兼顾性能和隔离性。但对于数据正确性非常敏感的场景,建议使用串行化级别。

Gap锁: 行锁演化技术

Gap锁可以有效防止幻读,了解这一技术能帮我们深刻理解行锁原理。

当我们用SELECT FOR UPDATE做行锁时,InnoDB会给每个返回的行都加锁。但这在范围查询时会有问题:

代码语言:javascript
复制
-- 事务1
SELECT * FROM table WHERE id BETWEEN 10 AND 20 FOR UPDATE; 

-- 事务2
INSERT INTO table VALUES 15; -- 未锁定的gap,可以插入!

InnoDB引入了Gap锁解决这个问题。在事务1的查询返回后,它会锁定所有之间的gap,阻止插入:

代码语言:javascript
复制
-- 事务1加Gap锁
(10, 11) (11, 15) (15, 20) 

-- 事务2被阻塞
INSERT INTO table VALUES 15;

注意Gap锁在提交后会被释放,不会对其他事务造成影响。

SELECT... FOR UPDATE 实现行锁

MySQL的行锁可以实现非常精细的并发控制,有效防止丢失更新。

SELECT ... FOR UPDATE可以对查询结果集中的行加互斥锁,阻止其他事务对这些行的更新:

代码语言:javascript
复制
-- 事务1
START TRANSACTION;
SELECT * FROM table WHERE id = 15 FOR UPDATE;

-- 事务2阻塞  
UPDATE table SET ... WHERE id = 15;

需要注意以下几点:

  • 只锁定真正查询到的行,未查询到的行不会被锁定;
  • 行锁会在事务提交后自动释放,不会长期阻塞其他事务;
  • 在锁定期间,其他事务仍可以查询数据,只是无法修改数据。

合理使用行锁,可以大大优化并发性能。

悲观锁和乐观锁使用场景

最后说一下乐观锁和悲观锁的使用场景。

悲观锁:每次访问数据时都认为会有并发修改,因此每次都会加锁。如SELECT FOR UPDATE

乐观锁:访问数据时认为不会有并发修改,只在提交时检查是否违反预期。如VERSION实现。

一般来说,乐观锁的性能和可伸缩性更好,但只能用于冲突较小的场景。而悲观锁适用于写操作频繁的场景。

所以我们要根据实际情况选择合适的锁机制,才能发挥事务的最大价值。

总结

以上就是今天要和大家分享的MySQL事务知识。希望这些经验和技巧能给你的工作带来一点启发。也欢迎你在评论区分享你的心得!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MySQL事务工作原理剖析
  • 事务的隔离级别选择
  • Gap锁: 行锁演化技术
  • SELECT... FOR UPDATE 实现行锁
  • 悲观锁和乐观锁使用场景
  • 总结
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com