Skip to content

Commit

Permalink
Consider transaction rolled back after failure
Browse files Browse the repository at this point in the history
  • Loading branch information
robsdedude committed Jan 19, 2024
1 parent c59bbe3 commit 9404020
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Add support for Bolt 5.2, which adds notification filtering.
- Add `Driver::is_encrypted()`.
- Reduce the number of lifetime generic parameters in `TransactionQueryBuilder` and `TransactionRecordStream`.
- Fix `Transaction::rolblack()` failing if a result stream failed before.

## 0.0.2
- Update dependencies.
Expand Down
16 changes: 14 additions & 2 deletions neo4j/src/driver/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,26 @@ impl<'driver, 'tx> Transaction<'driver, 'tx> {
/// This is the default behavior when the transaction is dropped.
/// However, when dropping the transaction, potential errors will be swallowed.
pub fn rollback(self) -> Result<()> {
self.drop_result.into_inner()?;
self.inner_tx.rollback()
match self.drop_result.into_inner() {
Ok(_) => self.inner_tx.rollback(),
Err(_) => {
// Nothing to do here.
// The transaction already failed and doesn't need to be rolled back.
Ok(())
}
}
}
}

/// A result cursor as returned by [`TransactionQueryBuilder::run()`].
///
/// It implements [`Iterator`] and can be used to iterate over the [`Record`]s.
///
/// Before ending the transaction ([`Transaction::commit()`] or [`Transaction::rollback()`]), all
/// record streams spawned from it must be dropped.
/// While calling [`drop(stream)`] works fine for this purpose, it will swallow any outstanding
/// errors.
/// Therefore, it is recommended to use [`TransactionRecordStream::consume()`] instead.
#[derive(Debug)]
pub struct TransactionRecordStream<'driver, 'tx>(
RecordStream<'driver>,
Expand Down
9 changes: 3 additions & 6 deletions testkit_backend/src/testkit_backend/responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,9 @@ static REGEX_SKIPPED_TESTS: OnceLock<Vec<(&'static Regex, &'static str)>> = Once

fn get_plain_skipped_tests() -> &'static HashMap<&'static str, &'static str> {
PLAIN_SKIPPED_TESTS.get_or_init(|| {
let mut map = HashMap::new();
map.insert(
"neo4j.test_tx_run.TestTxRun.test_tx_res_fails_whole_tx",
"backend (SessionHolder) doesn't keep result buffers around after error",
);
map
HashMap::from([
// ("path.to.skipped_test", "reason"),
])
})
}

Expand Down
13 changes: 4 additions & 9 deletions testkit_backend/src/testkit_backend/session_holder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,15 +470,10 @@ impl SessionHolderRunner {
}
Err(err) => {
known_transactions.insert(id, TxFailState::Failed);
// outside the receiver, we'll just reply with an
// error to the command. So query and parameters
// don't matter.
_ = buffered_command.insert(TransactionRun {
transaction_id: command.transaction_id,
query: String::from(""),
params: None,
}.into());
break Err(err);
let msg = TransactionRunResult {
result: Err(err.into()),
};
tx_res.send(msg.into()).unwrap();
}
}
}
Expand Down

0 comments on commit 9404020

Please sign in to comment.