mysql 出现锁 如何手工提交_请教,mysql事务,锁和交易问题?

隔离级别有四种,可串行化,可重复读,已提交读,未提交读。

一般数据库都是默认运行在已提交读的情况上,但是innodb是运行在可重复读的隔离级别上。

问题1:请问这个时候用事务的SERIERLIZED 隔离级别是否可以解决此问题。

肯定可以。这个是最高的隔离级别,等价于所有事务是串行执行,因此不会产生并发的问题。

简单重设下事务:

比如账户余额有100块钱,交易时检测如果 余额大于交易额,就交易成功。现在假设这个用户同一时刻,产生了多比交易,检测的时候就会出现问题。

事务可以用伪代码表示:

begin

read A

if(A>B)

than write(A-B)

commit

假设两个上面的事务并发执行,那么肯定是会出现问题:

--T1-- --T2--

begin begin

read A read A

if(A>B) if(A>B)

than write(A-B) than write(A-B)

commit commit

由于read A通常是使用类似select balance from tbl,这种属于不加锁的读,也就是说这种情况下不会加任何的锁。确保重复读只是在第一次read的时候创建快照。也就是说,T1的read A,第一次读到的是100元,而T2的read A也是读到了100元。

这个时候,业务逻辑if(A>B),假设T1的B为99元,T2的B为98元,则都为真,因此虽然在write(A-B)先执行的事务中会加上写锁,但是最后的结果是这两笔交易都能成功进行,因此会造成交易异常。

那么如果增加写锁呢?

--T1-- --T2--

begin begin

read A lock read A lock

if(A>B) if(A>B)

than write(A-B) than write(A-B)

commit commit

通过这个时候会使用select...for update语句。当事务执行该语句的时候,会获得所需的锁。

不管哪个事务先执行,select..for update都会对A加上写锁,因此两个事务是不会冲突的。

但是,这种情况下(属于悲观锁),对于短事务是一种可行的方案。但是对于长事务来说,性能开销太大了。因此当应用场景是在长事务下,可以使用乐观锁来实现。

问题2:或者给这行数据加锁,那请问这个锁该怎么加?

可以这么加:select *from tbl where id=xxx for update;

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论

打赏作者

竹谭

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值