Laravel 事务中 使用 悲观锁 小结

laravel 提供了方便快捷的数据库事务使用方式,在使用中遇到过几个容易混淆和被误导的地方,这里做个记录,希望哪里写的不对的地方各位大神指点一下
laravel 事务分为手动方式和自动方式,但如果我们在使用 laravel 提供的 sharedLock 或者 lockForUpdate 锁表的方式,为了避免不必要的麻烦和错误,建议最好使用手动提交事务来处理,如下图:

laravel 事务中 使用 悲观锁 小结

下面来说说 sharedLock(共享锁) 和lockForUpdate(悲观锁) 这两个在使用上的区别和影响

  1. sharedLock(共享锁)
    sharedLock 使用时等同于SQL语句 select * from transaction_test where type = 1 lock in share mode;
    在事务中使用 sharedLock 时才会生效,会把数据所在行进行锁定,此时被锁定的数据,不允许被其他操作修改,但是被锁定的数据,对查询操作没有影响,无论是普通查询还是事务中的查询操作,都不会受到影响.被锁定的数据,直到事务被提交或者回滚之后,才会释放.

  2. lockForUpdate(悲观锁)
    lockForUpdate 使用时等同于SQL语句 select * from transaction_test where type = 1 for update;
    lockForUpdate只有在事务中才会生效,使用lockForUpdate时数据所在行被锁定,此刻其他事务中的锁表操作会等待当前事务提交才会执行,但是对于非锁表和普通的查询操作并没有限制,有影响的只是你在事务中同样执行的锁表操作.

    总之,无论是共享锁还是悲观锁,受影响的只是事务中执行锁表的操作,对于普通的查询操作,和事务中的非锁表操作没有影响,
    同时需要注意的是,无论悲观锁还是共享锁当sql语句涉及到索引,并用索引作为查询或判断的依据时,那么mysql会用行级锁锁定所要修改的行,否则会使用表锁锁住整张表,因此在使用时一定要注意使用索引,否则会导致高的并发问题;

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 3

请问这两个是高并发情况下,只能在事务中应用吗?

4年前 评论

我刚刚试了一下 lockforupdate 先锁住之后, 不在事务里面执行 db::table('table')->lockforupdate()->first() 也会等待解锁

3年前 评论
LW_aravel (楼主) 3年前

我试了一下,事务里 使用lockforupdate sleep(20) ,在其他请求中 在读这一条数据,依然可以读到,还能修改,, 请问这是怎么回事呢?

file

3年前 评论
upeng 3年前
巴啦啦小仙女 (作者) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!