Laravel 5.1中的表锁定问题

5

我无法使用此查询锁定MySQL表:

DB::statement('LOCK TABLES imports WRITE');

它会产生以下异常:
[Illuminate\Database\QueryException]

SQLSTATE[HY000]: 一般错误: 2014 当其他未缓冲查询处于活动状态时无法执行查询。考虑使用PDOStatement::fetchAll()。或者,如果您的代码只会针对mysql运行,可以通过设置PDO::MYSQL_ATTR_USE_BUFFERED_QUERY属性来启用查询缓冲。(SQL: LOCK TABLES imports WRITE)
当我使用PDO时也会出现相同的错误。
我应该如何解决这个问题?

尝试使用 DB::connection()->getPdo()->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); - Siper
好的,我在文档中看到你只能锁定表以进行更新或共享。您可以使用DB :: table('imports') - > lock($ lockUpdate);来实现。 - Siper
2个回答

6
如果您想锁定整个表格并且希望使用LOCK TABLES table_name WRITE,则应以这种方式调用:DB::unprepared('LOCK TABLES imports WRITE');但是,如果您只想在所选行上应用锁定,则使用sharedLock()lockForUpdate()是正确的方法,因此它将返回并锁定仅选定的行。

1
注意:这将锁定表以进行读取和写入。它将保持锁定状态,直到使用“DB :: unprepared('UNLOCK TABLES')”为止。 - jonlink

3
// prevent rows from being modified until you're finished
DB::table('imports')->where('total', '>', 10)->sharedLock()->get();

使用 lockForUpdate() 来防止其他共享锁修改或选择相同的行。


5
你好,锁什么时候会解除? - supersan
NB: sharedLock 会锁定一行(而不是整个表)的写入。回答你的问题,Supersan,它会在事务完成后释放。 - jonlink
1
@jonlink,如果我有两个线程访问我的数据库,并且我正在使用sharedLock来避免冲突,那么如果第二个线程想要通过事务进行更新但无法进行,因为第一个事务已经锁定了,会发生什么?线程会等待还是直接抛出错误,这意味着我需要捕获它以重新尝试...或者是否有等待时间和超时? - LearningPath

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接