我正在尝试在我的模型中增加一个完全独立于模型的自动递增 ID 的非自动递增整数列。
为了简化我想说的话,考虑一张放书的桌子。在此表中,我们有四个字段:
Book_id (auto incrementing ID)
book_title (a string)
book_contents (Also a string for the purposes of this example)
book_edition (an integer representing the edition of the book. Think College textbooks)
因此,假设我们有一本名为"哈利波特"的书和另一本名为"米老鼠"的书。我们的数据库目前看起来像这样
id: 1
book_title: "Harry Potter"
book_contents: "Book Contents"
book_edition: 1
--------------------------
id: 2
book_title: "Mickey Mouse"
book_contents: "This is a book about Mickey"
book_edition: 1
现在让我们说,出于某种原因,"哈利波特"的书必须进行重大更改,无论是为了"导演剪辑版"还是其他任何相当于这本书的原因。此条目将如下所示
id: 3
book_title: "Harry Potter"
book_contents: "Updated book contents"
book_edition: 2
我的问题是,在Laravel 5+中获取原书版本的最佳方法是什么?
我是否需要实际执行Model::where({{查询以获取最新}}),或者我可以以另一种方式处理此问题?我看到有一个增量函数,但它没有很好地记录
作为次要问题,如果我确实做了一个模型::如上所述,如果我将其包装在 Laravel DB::transaction 中,我是否可以免受两个人同时更新哈利波特书的可能竞争条件的影响?例
function saveBook()
{
DB::transaction(function ($arr) {
$latest = Book::where('book_title', '=', 'Harry Potter')->orderBy("book_edition", "desc")->first();
$this->book_edition = $latest->book_edition + 1;
$this->save();
});
}
这里是否有可能遇到竞争条件?提前感谢!
从book_title
和book_edition
创建复合唯一索引应该从一开始就解决问题:
ALTER TABLE `books` ADD UNIQUE `unique_edition`(`book_title`, `book_edition`);
在这种情况下,添加事务不会带来任何好处,因为您只执行一个写入操作,虽然该操作取决于读取操作的结果,但唯一索引约束已经保护该操作免受任何竞争条件的影响。
要处理唯一异常,您可以执行以下操作:
function saveBook()
{
...
$latestEdition = Book::where('book_title', 'Harry Potter')->max('book_edition');
$this->book_edition = $latestEdition + 1;
try {
$this->save();
} catch (Illuminate'Database'QueryException $e) {
// Your checking for 1062 because that's
// the MySQL error message for duplicate entry
if ($e->errorInfo[1] == 1062) {
// set your error message here
}
}
...
}
您也可以查看使用悲观锁定,但只能作为替代方法,因为如果您已经在使用唯一约束,锁定将是多余的。但在这种情况下,唯一约束更有意义。