如果update(phone+id为主键)在insert之后,那么行级锁的时间为update+insert。
反之,行级锁的时间只有一个insert。
是谁先拿到行锁就先执行谁的秒杀吗?没搞懂
MySQL的innodb存储引擎支持行级锁,innodb的行锁是通过给索引项加锁实现的,这就意味着只有通过索引条件检索数据时,innodb才使用行锁,否则使用表锁。
根据当前的数据更新语句(UPDATE user set name=‘11111’ where account=‘1’),该条件字段account并没有添加索引,所以导致数据表被锁。
insert只会锁当前行,别人insert和你insert不冲突。 而update就不一样了。 比如大家都要更新1000元抢Iphone6更新,那么就会抢同一行的锁
为了spring的事务控制器识别这个运行时异常,进而回滚事务。
1.网络延时,只要有网络请求就会存在网络延时.2.行级锁只是锁住那一行的数据操作.对其他表和库没有影响.不会. 以上只是个人见解...
存储过程和事务各有各的用处。
存储过程相当于数据库上的编程语言
事务是为了满足ACID的一种机制。
数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。
只有在commit的时候 内部逻辑才被"真正"执行 映射到表里 没commit之前所有操作都在内存执行
首先是在更新操作的时候给行加锁,插入并不会加锁,如果更新操作在前,那么就需要执行完更新和插入以后事务提交或回滚才释放锁,而如果插入在前,则更新完以后事务提交或回滚就释放锁。也就是说是更新在前加锁和释放锁之间两次的网络延迟和GC,如果插入在前则加锁和释放锁之间只有一次的网络延迟和GC,也就是减少的持有锁的时间。
我没明白,能说说吗?
中执行update操作时会用到行级锁,调换顺序则减少了持有锁的时间
原来执行的流程
update(发送在mysql网络时间+gc时间) + insert(发送在mysql网络时间+gc时间)
因为update同一行会导致行级锁,而insert是可以并行执行的。
1.如果先update, update在前面会加锁
锁 + update(发送在mysql网络时间+gc时间) + insert(发送在mysql网络时间+gc时间) + 提交锁
其实的线程就要等,这个锁提交才能执行。
2.如果先insert,
insert(发送在mysql网络时间+gc时间) + 锁+ update(发送在mysql网络时间+gc时间) + 提交锁
其实的线程可以并发insert. 这样子会减少锁的时长
http://www.jianshu.com/p/ea7ef2d29940这里就是答案
我觉得,你提的问题是个BUG,不过在捕获到update失败后,我们可以再把插如的数据删除,以此实现补救,并且这种情况应该发生的不多,对整体性能影响不大.
是的,可以优化。这样做的目的就是降低行级锁持有的时间。
看了前面同学的问题和老师的回答明白了,mysql的update操作自带行锁。
https://github.com/MagicERP/seckill 慕课网Java高并发秒杀(课程)-代码完整优化版
看下关系数据库事务和锁方面的资料。
因为insert不涉及行解锁。
持有行级锁是在update上,释放锁是在commit(spring控制),也就是锁持有时间是update和commit之间的时间。这个过程网络请求越少,锁持有时间就越短。
实际业务会很复杂 跨多个数据源的时候就不能简单用存储过程来解决