Fix concurrent saves
This commit is contained in:
parent
c0a19c2a7e
commit
0c77cf2b40
|
@ -5,8 +5,8 @@ import {
|
|||
processFormulas,
|
||||
} from "../../../utilities/rowProcessor"
|
||||
import { FieldTypes, FormulaTypes } from "../../../constants"
|
||||
import { context } from "@budibase/backend-core"
|
||||
import { Table, Row } from "@budibase/types"
|
||||
import { context, locks } from "@budibase/backend-core"
|
||||
import { Table, Row, LockType, LockName } from "@budibase/types"
|
||||
import * as linkRows from "../../../db/linkedRows"
|
||||
import sdk from "../../../sdk"
|
||||
import isEqual from "lodash/isEqual"
|
||||
|
@ -149,12 +149,22 @@ export async function finaliseRow(
|
|||
await db.put(table)
|
||||
} catch (err: any) {
|
||||
if (err.status === 409) {
|
||||
const updatedTable = await sdk.tables.getTable(table._id!)
|
||||
let response = processAutoColumn(null, updatedTable, row, {
|
||||
// Some conflicts with the autocolumns occurred, we need to refetch the table and recalculate
|
||||
await locks.doWithLock(
|
||||
{
|
||||
type: LockType.AUTO_EXTEND,
|
||||
name: LockName.PROCESS_AUTO_COLUMNS,
|
||||
resource: table._id,
|
||||
},
|
||||
async () => {
|
||||
const latestTable = await sdk.tables.getTable(table._id!)
|
||||
let response = processAutoColumn(null, latestTable, row, {
|
||||
reprocessing: true,
|
||||
})
|
||||
await db.put(response.table)
|
||||
row = response.row
|
||||
}
|
||||
)
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
|
|
|
@ -189,25 +189,32 @@ describe("sdk >> rows >> internal", () => {
|
|||
})
|
||||
|
||||
await config.doInContext(config.appId, async () => {
|
||||
for (const row of makeRows(30)) {
|
||||
for (const row of makeRows(5)) {
|
||||
await internalSdk.save(table._id!, row, config.user._id)
|
||||
}
|
||||
await Promise.all(
|
||||
makeRows(200).map(row =>
|
||||
makeRows(10).map(row =>
|
||||
internalSdk.save(table._id!, row, config.user._id)
|
||||
)
|
||||
)
|
||||
for (const row of makeRows(20)) {
|
||||
for (const row of makeRows(5)) {
|
||||
await internalSdk.save(table._id!, row, config.user._id)
|
||||
}
|
||||
})
|
||||
|
||||
const persistedRows = await config.getRows(table._id!)
|
||||
expect(persistedRows).toHaveLength(250)
|
||||
expect(persistedRows).toHaveLength(20)
|
||||
expect(persistedRows).toEqual(
|
||||
expect.arrayContaining(
|
||||
Array.from({ length: 20 }).map((_, i) =>
|
||||
expect.objectContaining({ id: i + 1 })
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
const persistedTable = await config.getTable(table._id)
|
||||
expect((table as any).schema.id.lastID).toBe(0)
|
||||
expect(persistedTable.schema.id.lastID).toBe(250)
|
||||
expect(persistedTable.schema.id.lastID).toBe(20)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -21,6 +21,7 @@ export enum LockName {
|
|||
PERSIST_WRITETHROUGH = "persist_writethrough",
|
||||
QUOTA_USAGE_EVENT = "quota_usage_event",
|
||||
APP_MIGRATION = "app_migrations",
|
||||
PROCESS_AUTO_COLUMNS = "process_auto_columns",
|
||||
}
|
||||
|
||||
export type LockOptions = {
|
||||
|
|
Loading…
Reference in New Issue