mysql: 三级封锁协议

上周我听到有人谈论 3 级锁定协议。

这在MySQL中非常重要。

如果是主阻塞协议,必须先加X锁。
数据修改必须加锁。
只有修改事务完成后锁才会被释放。

这是我在查2 02 3 年的资料时写的,目的是为了防止修改丢失。

二级阻塞协议,加S锁定读取数据。
看完后请解锁。

该协议可以防止脏读。
然而,它不能被重复读取,并且可能无法阻止这种情况。

S锁,一种三级阻塞协议,持续到事务完成为止。

这样就保证了可重复读取。

我的朋友在使用MySQL时经常使用REPEATABLE READ。

这对应于3 级封锁协议。

你必须了解X锁和S锁。

X锁,独占锁。
用于更改数据。
一旦锁定,其他人就无法锁定它。

S锁,共享锁。
用于读取数据。
一旦锁定,其他人也可以添加 S 锁。

常规 SELECT 不需要锁定。
UPDATE DELETE INSERT 需要 X 锁。

选择... 在共享模式下添加锁 S 锁。

我不确定这张特定照片是如何显示的。

算了。

如何给mysql表上锁

我上周尝试过 SELECT...FORUPDATE 一次。
2 02 3 年 1 0 月 2 5 日,MySQL。

在阻塞时,数据还没有被其他人改变过。
好的。

LOCKTABLES 不经常使用。
2 02 3 年 5 月 1 2 日,在一个旧项目中看到。
表被锁定以写入数据。
然后我就忘记解锁了,算了。

UNLOCK TABLE,使用时解锁。
2 02 3 年8 月3 日写存储过程的时候记得加一句。

表锁是为了防止别人随意修改。
2 02 3 年1 1 月1 8 日,在测试时,我发现当其他人插入数据时,我的请求会等待。
知道了。

DROPTABLE 也是可能的。
2 02 3 年7 月9 日,我不小心尝试锁定桌子。
记得报告错误。

我不确定是否所有引擎都支持这部分。
没关系。

mysql select for update 什么时候解除锁定 ? 就是说 是不是要等到java的connection,commit了或者rollback

老实说,我觉得你问这个问题很有趣。
我之前在项目中使用 SELECT...FOR UPDATE 时遇到过陷阱。
你提到的这三个措施确实需要分开考虑。

数据库断开连接最直接的方法是,如果运行FOR UPDATE的连接突然中断,比如客户端程序崩溃或者网络连接丢失,数据库会释放锁定的行。
因为连接丢失,所以没有地方提交或回滚事务。
数据库必须自行释放锁。
否则整个系统将停留在那里。
我记得这会导致我们的测试环境中的连接断开,而其他人则无法选择整个表。
最终确认客户端挂断,问题没有得到处理。

Commit也是解锁的标准操作。
SELECT ... FOR UPDATE 后跟 UPDATE/DELETE/INSERT 最后提交结束事务并自然释放锁。
例如,上次更改订单状态时,我使用 FOR UPDATE 来选择未处理的订单,然后遍历提交来更新状态。
整个过程结束后,锁就消失了。

回滚也是如此。
如果事务期间出现问题,例如引发异常或手动回滚的代码,锁定的行也会被解锁。
我曾经让一位同事编写了一个批处理脚本,但是在中间捕获了一个异常,并且锁仍然被持有,因为它没有被捕获。
最后数据库监视器给了我一个警报,我花了3 0分钟才弄清楚。

有趣的是,如果连接丢失但没有提交/回滚,锁会一直保持到超时。
我们之前已经在 Oracle 上做过这件事,它与 MySQL 类似。
因此,当使用FOR UPDATE时,必须显式提交或回滚并避免中止事务。

我个人从未遇到过分布式事务锁定场景,但理论上来说,如果您的连接跨越多个节点或使用某种分布式事务协议,则在更新时处理断开连接、提交和回滚可能会更加复杂。
我记得数据在X左右,但我建议查看官方文档。