Я автор арана gojs. Для потомков я хотел бы уточнить, что этот ответ о aran gojs 6, который является текущим выпуском aran gojs на момент написания этой статьи и версии, в которой впервые была добавлена поддержка потоковой передачи. сделки. API может измениться в будущих версиях, хотя в настоящее время нет планов сделать это.
Из-за того, как работают транзакции (по состоянию на gojs 6), вам необходимо обратить особое внимание на предостережение упоминается в документации для метода run
:
Если данная функция содержит асинхронные логики c, в транзакции будет выполняться только синхронная часть функции , Например, при использовании async / await в транзакции будет выполняться только код до первого await. Обратите внимание на приведенные ниже примеры.
Другими словами, функции async
, вероятно, будут работать неправильно, если вы просто заключите их в trx.run
. Я бы рекомендовал передавать объект транзакции каждой функции и заключать вызовы методов в эти функции в trx.run
.
Например:
async runQuery(query, trx) {
try {
const cursor = await trx.run(() => this.arangodb.query(query))
return trx.run(() => cursor.all())
} catch (error) {
logger.error('ArangoDB query failed', { stack: error })
throw error
}
}
async touchDocument(id, revision, trx) {
const type = await this.getObjectTypeFromId(id, trx)
const collection = await this.getCollection(type, false, true, trx)
const idCollection = await this.getCollection(ID_COLLECTION, false, true, trx)
const touchAql = aql`
LET permanentDocId = DOCUMENT(${idCollection}, ${id}).docId
LET permanentDoc = MERGE( DOCUMENT(permanentDocId), { _rev : ${revision} })
UPDATE permanentDoc WITH permanentDoc in ${collection} OPTIONS { ignoreRevs: false }
RETURN NEW
`
return this.runQuery(touchAql, trx)
}
this.touchDocument(parentId, parentRevision, trx)
Причина этого заключается в том, что trx.run
устанавливает весь драйвер в «режим транзакции», выполняет данную функцию и затем отключает «режим транзакции» после его выполнения, чтобы не связанный код случайно не запустился в транзакции.
Недостаток этого подхода заключается в том, что если функция asyn c и содержит несколько операторов await
, в транзакции будет выполняться только код, предшествующий и включающий в себя первый await
. В вашем коде это означает, что «режим транзакции» отключен после возврата this.getObjectTypeFromId(id)
. Если этот метод сам содержит несколько await
выражений, опять-таки только первое будет частью транзакции (и т. Д.).
Надеюсь, это устранит некоторую путаницу.