Skip to content

Commit

Permalink
issue #1300 TxManagerImpl.nextTxNumber(): Repeat attempt on ArangoDB …
Browse files Browse the repository at this point in the history
…1200 error (racing cond.)
  • Loading branch information
wajda committed Jul 2, 2024
1 parent 1047324 commit 607a758
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 27 deletions.
10 changes: 5 additions & 5 deletions arangodb-foxx-services/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ mvn clean install
```shell
# Deploy the "/spline" service to the "foo" database on the given ArangoDB server
# (http://some.server:1234/_db/foo/spline/)
npm foxx:deploy --database=foo --server=http://some.server:1234
npm run foxx:deploy --database=foo --server=http://some.server:1234

# If the "--server" option is omitted, the local server is used
# (http://localhost:8529/_db/foo/spline/)
npm foxx:deploy --database=foo
npm run foxx:deploy --database=foo

# Use "foxx:deploy-dev" to deploy the service in development mode (https://www.arangodb.com/docs/stable/foxx-guides-development-mode.html)
npm foxx:deploy-dev --database=foo
npm run foxx:deploy-dev --database=foo

# If needed, in addition to the "foxx:deploy" script that executes build, uninstall and install steps,
# you can also use individual "foxx:install" or "foxx:uninstall" scripts with the same arguments.
npm foxx:uninstall --database=NAME [--server=URL]
npm foxx:install --database=NAME [--server=URL]
npm run foxx:uninstall --database=NAME [--server=URL]
npm run foxx:install --database=NAME [--server=URL]
```

---
Expand Down
61 changes: 39 additions & 22 deletions arangodb-foxx-services/src/main/services/txm/tx-manager-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { TxManager } from './tx-manager'
import {TxManager} from './tx-manager'
import {
AuxCollectionName,
CollectionName,
Expand All @@ -27,35 +27,52 @@ import {
TxParams,
WriteTxInfo
} from '../../persistence/model'
import { store } from '../store'
import { aql, db } from '@arangodb'
import {store} from '../store'
import {aql, db} from '@arangodb'
import * as Logger from '../../utils/logger'
import UpdateResult = ArangoDB.UpdateResult


/**
* Max attempts to atomically increment the counter
*/
const MAX_GET_TX_NUM_ATTEMPTS = 50

export class TxManagerImpl implements TxManager {

private nextTxNumber(): TxNum {
const curCnt: Counter = store.getDocByKey(CollectionName.Counter, 'tx')

// as of time of writing the '@types/arangodb:3.5.13' was the latest version,
// and it was not up-to-date with ArangoDB 3.10+ JavaScript API
// @ts-ignore
const updResult: UpdateResult<Counter> = db._update(
curCnt,
{
curVal: curCnt.curVal + 1
},
// @ts-ignore
{
overwrite: false, // check _rev
returnNew: true // return an updated document in the `new` attribute
let attempts = MAX_GET_TX_NUM_ATTEMPTS
while (attempts-- > 0) {
try {
const curCnt: Counter = store.getDocByKey(CollectionName.Counter, 'tx')

// as of time of writing the '@types/arangodb:3.5.13' was the latest version,
// and it was not up-to-date with ArangoDB 3.10+ JavaScript API
// @ts-ignore
const updResult: UpdateResult<Counter> = db._update(
curCnt._id,
{
curVal: curCnt.curVal + 1
},
// @ts-ignore
{
overwrite: false, // check _rev
returnNew: true // return an updated document in the `new` attribute
}
)

const newCnt: Counter = updResult.new

return newCnt.curVal
}
)

const newCnt: Counter = updResult.new

return newCnt.curVal
catch (e) {
const errNum = e.errorNum
if (errNum !== 1200) {
throw new Error(`Failed to obtain a new Tx number.\nUnderlying error ${errNum}: ${e.message}`)
}
}
}
throw new Error(`Failed to obtain a new Tx number after ${MAX_GET_TX_NUM_ATTEMPTS} attempts.`)
}

startWrite(txParams: TxParams = {}): WriteTxInfo {
Expand Down

0 comments on commit 607a758

Please sign in to comment.