我需要从设置为空闲的SQLite数据库中选择一行,然后将该行标记为已采用。选择和更新至关重要的是一个原子操作,并且不存在两个用户将相同的行返回为空闲状态的风险。Laravel 4与更新的独家交易和选择
不幸的是,Laravel在拨打DB::transaction
时似乎没有提供交易类型选择,如果我将它作为DB::statement
运行,那么我不会获取返回的值。
另外,由于SQLite不支持变量,我不能在select和update之间存储主键,所以我不确定它是否可以根据SQLite数据库运行它。
可以使用Laravel和SQLite吗?
如果没有,那么我需要在MySQL表中存储与SQLite数据库相关的下一个空闲ID,并在该行上使用锁定。在MySQL中按行锁定是否有任何主要的语法差异? (我不能承受意外锁定整个表)
我在看类似这样的语法:(当然除了SQLite的不支持变量)
BEGIN EXCLUSIVE TRANSACTION
SET @free = SELECT InternalID FROM main WHERE Called = 0 LIMIT 1;
UPDATE main SET Called = 1 WHERE InternalID = @free;
SELECT * FROM main LEFT JOIN lead ON main.InternalID = lead.InternalID WHERE main.InternalID = @free;
END TRANSACTION
因为我敢肯定有人会问:“你为什么使用两个数据库系统!?”:
SQLite dbs包含需要灵活数量的列的数据。这些数据将在几个月内每周使用几天,然后可以归档。需要有相当多的这些“小型数据库”。这些数据无法高效地存储在MySQL中(我以前替换的系统尝试过这种方式,而且速度非常慢)。每个SQLite数据库的并发性都非常低,但至关重要的是两个用户完全没有机会获得同一行 - 这在旧系统中发生过几次。
谢谢!我还可以将用户的帐户ID用作我的令牌,因为每个用户一次只能使用一行。 –
SQLite在更新中不支持'LIMIT',所以我不得不使用'UPDATE main SET CallerToken =? WHERE InternalID IN(SELECT InternalID FROM main WHERE CallState = 0 AND CallerToken IS NULL LIMIT 1)' –
非常感谢这篇文章。您首先将所需记录标记为锁定更新,然后使用select查询它们的模式 - 非常聪明! :-)它让我感到毛骨悚然,我自己并没有得到这个想法,哈哈......无论如何,这真的帮助我解决了一个相关的问题!谢谢! – preyz