【发布时间】:2020-09-05 12:47:38
【问题描述】:
我有以下 2 个数据库 (psql) 表定义如下:
create table product ( date date default CURRENT_DATE not null, updated_at timestamp(0) default CURRENT_TIMESTAMP(0) not null, product_id integer not null ) create table product_offer ( date date default CURRENT_DATE not null, updated_at timestamp(0) default CURRENT_TIMESTAMP(0) not null, product_id integer not null, offer_id integer not null, price decimal, constraint product_fkey foreign key (date, updated_at, product_id) references product )
在 Laravel 中,我的模型设置和关系定义如下:
public function offers() { return $this->belongsToMany('App\Offer', 'product_offer', 'product_id', 'offer_id') ->withPivot('date', 'updated_at','price'); }
我正在尝试在单个交易中创建新产品并为其附加报价:
$product = new Product; $product->product_id = 1; $offers = [1 => ['price' => 10]]; DB::beginTransaction(); try { $product->save(); $product->offers()->attach($offers); DB::commit(); } catch (\Exception $e) { DB::rollback(); }
但我从数据库中得到以下错误:
SQLSTATE[23503]:外键违规:7 错误:插入或更新 表“product_offer”违反外键约束“product_fkey” DETAIL: Key (date, updated_at, product_id)=(2020-05-19, 2020-05-19 12:19:47, 1) 不在“产品”表中。
能否请您告诉我解决此问题的最佳方法是什么?事务中的语句是否有可能乱序执行?还是 save() 方法可能会过早地提交事务?
请注意,上面的代码有时有效。例如,如果我进行 10 次尝试,则 50% 的时间交易成功,其余的我得到上述错误。
【问题讨论】:
-
第一:我认为你的外键约束不正确,第二:为什么不使用 Laravel 迁移表更容易。
-
根据我的经验,在 $product->offer() 被触发之前,$product->save() 不会在数据库服务器级别完成。为了妥协,我在 $product->offer().... 脚本之前从数据库重新加载 $product。例如,我在 $product->save() 之后做了一个 $product->fresh()
-
@nikistag 这就是我的想法,我将外键约束更改为可推迟到事务的提交,但问题仍然存在。此外,在没有任何更改的情况下,这有时会起作用,有时会不起作用,这让人认为 Laravel 事务处理不一致。
-
刷新我的模型解决了我的问题......你的呢?
标签: database laravel postgresql eloquent transactions