我试图在模型中增加一个非自动递增的整数列,它完全独立于模型的自动递增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

我的问题是什么是最好的方式去抓住原来的图书版本在拉维尔5+?
我真的需要做一个Model::where({{query to get latest})或者我可以用另一种方式来处理这个问题吗?我看到有一个增量函数,但是没有很好地记录下来
作为第二个问题,如果我做了一个Model::上面提到过的地方,如果我把它包装在一个Laravel DB::事务中,我是否受到保护,免受两个人同时更新哈利波特书的可能的竞争条件的影响?
例子
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_titlebook_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
        }
    }

    ...
}

您还可以查看使用Pessimistic Locking,但这只是一种替代方法,因为如果您已经使用了唯一约束,那么锁定将是多余的。但在这种情况下,唯一的约束更有意义。

关于php - Laravel在没有竞争条件的情况下保存之前获取最新的非增量值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35660260/

10-09 23:58