mysql transaction select for update及数据一致性处理实例分析

分类:编程技术 时间:2024-02-20 15:28 浏览:0 评论:0
0
小编给大家分享一个MySQL事务选择更新和数据一致性处理的实例分析。相信大多数人对此还不是很了解,所以分享这篇文章供大家参考。希望您读完本文后有所启发。收获,我们一起来了解一下吧!

MySQL中的事务默认是自动提交的,即autocommit = 1;

但是这样的话,在某些情况下会出现问题:例如:

如果要一次性插入1000条数据,mysql就会commit 1000次。

p>

如果我们关闭自动提交[autocommit=0],通过程序来控制,那么只需要一次commit就够了。 ,这样才能更好的体现交易的特点!

对于需要操作的数值,比如金额、数量等!

记住一个原则:一次锁、两次判断、三次更新

在MySQL的InnoDB中,默认的Tansaction隔离级别为REPEATABLE READ(可重读)

SELECT中的读锁定主要分为两种方式:

SELECT ... LOCK IN SHARE MODE

p>

SELECT ... FOR UPDATE

当事务(Transaction)正在进行时,SELECT到同一个数据表,这两种方法必须等待其他事务数据提交(Commit)执行前。

主要区别在于,当一方想要更新同一个表单时,LOCK IN SHARE MODE 很容易导致死锁。

简单来说,如果要在SELECT之后UPDATE同一个表单,最好使用SELECT ... UPDATE。

例如:

假设产品表单products中有一个数量来存储商品的数量。订单建立之前,必须判断商品数量是否充足(数量>0),然后将数量更新为1即可。代码如下:

从 id=3 的产品中选择数量;更新产品SET quantity = 1 WHERE id=3;

为什么不安全?

量少可能不会有问题,量大了可能会出现问题数据的访问肯定会出现问题。如果我们需要在数量>0时扣除库存,假设程序在第一行SELECT中读取到的数量是2。看起来这个数字是正确的,但是当MySQL准备UPDATE时,可能有人已经扣除了库存。变成了0,但是程序并不知道,继续错误的UPDATE。因此必须采用事务机制来保证数据读取和提交的正确性。

所以我们可以在MySQL中测试一下,代码如下:

SET AUTOCOMMIT=0;开始工作; SELECT amount FROM products WHERE id=3 FOR UPDATE;

此时products数据中id=3的数据被锁定(注3),其他交易必须等待该交易提交后才能进行它们可以被执行 SELECT* FROM products WHERE id=3 FOR UPDATE 这确保了其他交易中按数量读取的数字是正确的。

更新产品设置数量 = '1' WHERE id=3 ; COMMIT WORK;

提交已写入数据库并且产品已解锁。

注1:BEGIN/COMMIT是事务的起点和终点。您可以使用两个以上的 MySQL 命令窗口来交互式观察锁定状态。

注2:在一个事务中,只有同一数据的SELECT...FOR UPDATE或LOCK IN SHARE MODE才会等待其他事务完成后才执行。一般来说,SELECT...不会受此影响。 。

注3:由于InnoDB默认是行级锁。关于数据列锁定,请参考这篇文章。

注4:尽量不要在InnoDB表单中使用LOCK TABLES命令。如果一定要使用,请先阅读官方关于InnoDB中LOCK TABLES使用说明,避免系统频繁出现死锁干。

MySQL SELECT ... FOR UPDATE的行锁和表锁

上面介绍了SELECT ... FOR UPDATE的用法,但你要注意锁定(Lock)数据的判断。由于InnoDB默认是行级锁,只有“显式”指定主键时,MySQL才会执行行锁(只锁定选定的数据)。否则,MySQL将执行Table Lock(锁定整个数据表)。 )。

例如:

假设有一个表单products,它有两个字段:id和name,id为主键。

示例1:(显式指定主键,并有此数据,行锁)

SELECT * FROM products WHERE id='3' FOR UPDATE ;

示例 2:(无主键,表锁)

SELECT * FROM products WHERE name='Mouse' FOR UPDATE;< /pre> 

示例3:(主键不明确,表锁)

SELECT * FROM products WHERE id<>'3' FOR UPDATE;

示例4:(主键不明确,表锁)

SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;

乐观锁和悲观锁策略

悲观锁:读取数据时加锁对于那些行,其他对这些行的更新需要等到悲观锁结束后才可以进行可以继续。

乐观:读取数据时不加锁。更新时,检查数据是否已更新。如果是这样,请取消当前更新。一般我们只有在悲观锁的等待时间太长、无法接受的情况下才会这样做。选择乐观锁定。

以上就是《MySQL Transaction Select进行更新与数据一致性处理示例分析》一文的全部内容。感谢您的阅读!相信大家都有一定的了解,希望分享的内容对大家有所帮助。如果您想了解更多知识,请付费关注行业资讯频道!

1. 本站所有资源来源于用户上传或网络,仅作为参考研究使用,如有侵权请邮件联系站长!
2. 本站积分货币获取途径以及用途的解读,想在本站混的好,请务必认真阅读!
3. 本站强烈打击盗版/破解等有损他人权益和违法作为,请各位会员支持正版!
4. 编程技术 > mysql transaction select for update及数据一致性处理实例分析

用户评论