Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lock for update implementation on 9x #876

Open
gdonnari opened this issue Aug 6, 2024 · 3 comments
Open

Lock for update implementation on 9x #876

gdonnari opened this issue Aug 6, 2024 · 3 comments

Comments

@gdonnari
Copy link

gdonnari commented Aug 6, 2024

Summary of problem or feature request

I´m facing this issue with yajra/laravel-oci8 9x
I can see it was fixed here
The fix was merged in 10x, but not in 9x.
It is possible to apply this fix on latest 9x branch?

System details

  • Operating System: Linux
  • PHP Version: 8.0.28
  • Laravel Version: 9x
  • Laravel-OCI8 Version: 9x
@yajra
Copy link
Owner

yajra commented Aug 7, 2024

Sure, will check if the PR can be merged to 9.x when I get the chance. If you can, please do not hesitate to submit a PR. Thanks!

@gdonnari
Copy link
Author

gdonnari commented Aug 7, 2024

Hi Arjay,

When testing the merge locally I detected that this fix brokens other use cases.

If the query uses a distint, orderby, groupby, etc then Oracle raises ORA-02014 when for update is also set.

For example, this code extracted from Laravel DatabaseQueue.php:

protected function getNextAvailableJob($queue)
    {
        $job = $this->database->table($this->table)
                    ->lock($this->getLockForPopping())
                    ->where('queue', $this->getQueue($queue))
                    ->where(function ($query) {
                        $this->isAvailable($query);
                        $this->isReservedButExpired($query);
                    })
                    ->orderBy('id', 'asc')
                    ->first();
        ...
    }

Currently the generated SQL is:

select * from "TBL_JOB" 
where "QUEUE" = :p0 and (("RESERVED_AT" is null and "AVAILABLE_AT" <= :p1) or ("RESERVED_AT" <= :p2)) 
order by "ID" asc for update

This query does not honor ->first() which is the original issue reported, and locks all the returned records instead of the first one. This causes large processes to take a huge ammount of time to complete.

Now, with the fix applied it honors ->first() but it raises ORA-02014.
The generated query is:

select * from (
select * from "TBL_JOB" 
where "QUEUE" = :p0 and (("RESERVED_AT" is null and "AVAILABLE_AT" <= :p1) or ("RESERVED_AT" <= :p2)) 
order by "ID" asc
) where rownum = 1 
for update;

So, I'm not sure what the correct patch is, in order to fully honor the query builder in the example.
Think this require futher analisys.

@yajra
Copy link
Owner

yajra commented Aug 8, 2024

I think this PR #834 also needs to be merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants