mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
chore: fix concurrent CommitQuota
transactions for unrelated users/orgs (#15261)
The failure condition being fixed is `w1` and `w2` could belong to different users, organizations, and templates and still cause a serializable failure if run concurrently. This is because the old query did a `seq scan` on the `workspace_builds` table. Since that is the table being updated, we really want to prevent that. So before this would fail for any 2 workspaces. Now it only fails if `w1` and `w2` are owned by the same user and organization.
This commit is contained in:
@ -6736,23 +6736,33 @@ const getQuotaConsumedForUser = `-- name: GetQuotaConsumedForUser :one
|
||||
WITH latest_builds AS (
|
||||
SELECT
|
||||
DISTINCT ON
|
||||
(workspace_id) id,
|
||||
workspace_id,
|
||||
daily_cost
|
||||
(wb.workspace_id) wb.workspace_id,
|
||||
wb.daily_cost
|
||||
FROM
|
||||
workspace_builds wb
|
||||
-- This INNER JOIN prevents a seq scan of the workspace_builds table.
|
||||
-- Limit the rows to the absolute minimum required, which is all workspaces
|
||||
-- in a given organization for a given user.
|
||||
INNER JOIN
|
||||
workspaces on wb.workspace_id = workspaces.id
|
||||
WHERE
|
||||
workspaces.owner_id = $1 AND
|
||||
workspaces.organization_id = $2
|
||||
ORDER BY
|
||||
workspace_id,
|
||||
created_at DESC
|
||||
wb.workspace_id,
|
||||
wb.created_at DESC
|
||||
)
|
||||
SELECT
|
||||
coalesce(SUM(daily_cost), 0)::BIGINT
|
||||
FROM
|
||||
workspaces
|
||||
JOIN latest_builds ON
|
||||
INNER JOIN latest_builds ON
|
||||
latest_builds.workspace_id = workspaces.id
|
||||
WHERE NOT
|
||||
deleted AND
|
||||
WHERE
|
||||
NOT deleted AND
|
||||
-- We can likely remove these conditions since we check above.
|
||||
-- But it does not hurt to be defensive and make sure future query changes
|
||||
-- do not break anything.
|
||||
workspaces.owner_id = $1 AND
|
||||
workspaces.organization_id = $2
|
||||
`
|
||||
|
Reference in New Issue
Block a user