1

I tried this:

$result = (array)DB::selectOne('SELECT * FROM campaign WHERE id = ? FOR UPDATE', [$data['campaign_id']]);
$campaign = new Campaign($result);
$campaign->counter += 1;
$campaign->save();

But I get this error on save Integrity constraint violation: 1062 Duplicate entry '1' for key, because it thinks I'm trying to work with a new campaign, not an existing one.

Edit: Why doesn't it know it exists, considering I have the primary key set.

Farzher
  • 13,934
  • 21
  • 69
  • 100
  • why aren't you using Eloquent or fluent instead? – Cody Covey Jul 08 '13 at 03:09
  • I think what I'm doing is too advanced for eloquent. I need to lock table rows. You can see I'm using `FOR UPDATE` in my query. I couldn't figure out how to do that, or anything custom with eloquent. – Farzher Jul 08 '13 at 03:12
  • Would defining a transaction explicitly (as [show here](http://stackoverflow.com/questions/15105640/laravel-eloquent-orm-transactions)) be of help? – fideloper Jul 08 '13 at 13:03
  • Yeah, my code is already inside a transaction – Farzher Jul 08 '13 at 14:02

2 Answers2

3

One way to do it would be to set the $exists property to true before saving the object.

$campaign->exists = true;
$campaign->save();

This way it will trigger the performUpdate() method instead of performInsert().

Kemal Fadillah
  • 9,760
  • 3
  • 45
  • 63
  • I think it's weird that I have to manually say it exists, but I guess the exists property is public for a reason. Looks good, I'll mark correct if it works. – Farzher Jul 08 '13 at 14:15
0

How about this instead...

$campaign = Campaign::find((int) $data['campaign_id']);

$campaign->counter += 1;

$campaign->save();

mavrck
  • 1,883
  • 1
  • 10
  • 15