Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
06-15-2022 07:35 AM - edited 06-15-2022 07:37 AM
session := r.driver.NewSession(neo4j.SessionConfig{
DatabaseName: r.dataBaseName,
AccessMode: neo4j.AccessModeWrite,
})
defer session.Close()
result, err := session.WriteTransaction(func(tx neo4j.Transaction) (interface{}, error) {
result, err := tx.Run(q, params)
if err != nil {
return nil, err
}
record, err := result.Single()
if err != nil {
return nil, err
}
//@TODO tx.Commit() // ??
//@TODO tx.Rollback() // ??
node := record.Values[0].(dbtype.Node)
return r.nodeToEntity(node), nil
})
None of the documentation emphasizes the need to commit or rollback a transaction. In addition, in the documentation, I found a mention of operations with auto-commit behavior. Do I understand correctly that ReadTransaction (or WriteTransaction) is automatically commited, especially if only one request is executed inside it?
Solved! Go to Solution.
06-17-2022 01:58 AM - edited 07-27-2022 01:52 AM
Hello,
I agree this is confusing and the good news is: the confusion will be gone in 5.0 *.
When you are using session.WriteTransaction or session.ReadTransaction, the callback you provide (which we call a transaction function), receives a special kind of transaction: a managed transaction.
Since the transaction is managed internally, you must not call Commit, Rollback or Close yourself. In fact, if you do, you will systematically get an error. The driver will call these itself when appropriate.
How is the confusion gone in 5.0? The Transaction interface has been split into:
* Let me amend my initial statement a little bit. The confusion is not entirely gone in 5.0. In fact, the existing Transaction interface is still there but is deprecated. The main motivation for keeping the old interface around is to not complicate the migration path from 4.x to 5.0. The ExplicitTransaction and ManagedTransaction interfaces are exposed only when you use the new driver APIs that are context-aware (they had been requested for quite some time).
So far, we've talked about transactions that are initiated from the driver side. They're created via session.BeginTransaction and session.ReadTransaction/session.WriteTransaction.
There is another kind: auto-commit transactions. One may think this has to do with the automatic management of commits/rollbacks of transaction functions, but it is not. Auto-commit transactions are transactions that are created and managed entirely on the server side. This happens only when you call session.Run.
Some specific Cypher queries do not work with driver transactions, these are:
These must be executed with session.Run. These transactions managed on the server side are what we refer to as auto-commit transactions.
Somewhat surprisingly, auto-commit Cypher extensions (such as apoc.periodic.commit) can run in explicit transactions, but that's not a good idea.
Why?
Because auto-commit workloads spawn new transactions on their own. Rolling back the explicit transaction would have no effect onto the spawned, independent transactions. Moreover, if you ran more other queries in an explicit transaction, the transaction status report can get confusing: the explicit transaction could be committed (i.e. successful) even though some of the spawned transactions are not.
This leaves us with one final question: why not use session.Run all the time?
There are a few circumstances where session.Run is not a good fit:
In 5.0, you'll get the best of both worlds as a new reliable option: explicit transaction management with BeginTransaction and custom retry logic if you want to (an API to determine whether errors are safe to retry will be made publicly available).
This is A LOT to consider, isn't it? We're working hard to trying to simplify the API surface of the drivers and we'll hopefully be able to make your lives easier in the 5.x series.
06-17-2022 01:58 AM - edited 07-27-2022 01:52 AM
Hello,
I agree this is confusing and the good news is: the confusion will be gone in 5.0 *.
When you are using session.WriteTransaction or session.ReadTransaction, the callback you provide (which we call a transaction function), receives a special kind of transaction: a managed transaction.
Since the transaction is managed internally, you must not call Commit, Rollback or Close yourself. In fact, if you do, you will systematically get an error. The driver will call these itself when appropriate.
How is the confusion gone in 5.0? The Transaction interface has been split into:
* Let me amend my initial statement a little bit. The confusion is not entirely gone in 5.0. In fact, the existing Transaction interface is still there but is deprecated. The main motivation for keeping the old interface around is to not complicate the migration path from 4.x to 5.0. The ExplicitTransaction and ManagedTransaction interfaces are exposed only when you use the new driver APIs that are context-aware (they had been requested for quite some time).
So far, we've talked about transactions that are initiated from the driver side. They're created via session.BeginTransaction and session.ReadTransaction/session.WriteTransaction.
There is another kind: auto-commit transactions. One may think this has to do with the automatic management of commits/rollbacks of transaction functions, but it is not. Auto-commit transactions are transactions that are created and managed entirely on the server side. This happens only when you call session.Run.
Some specific Cypher queries do not work with driver transactions, these are:
These must be executed with session.Run. These transactions managed on the server side are what we refer to as auto-commit transactions.
Somewhat surprisingly, auto-commit Cypher extensions (such as apoc.periodic.commit) can run in explicit transactions, but that's not a good idea.
Why?
Because auto-commit workloads spawn new transactions on their own. Rolling back the explicit transaction would have no effect onto the spawned, independent transactions. Moreover, if you ran more other queries in an explicit transaction, the transaction status report can get confusing: the explicit transaction could be committed (i.e. successful) even though some of the spawned transactions are not.
This leaves us with one final question: why not use session.Run all the time?
There are a few circumstances where session.Run is not a good fit:
In 5.0, you'll get the best of both worlds as a new reliable option: explicit transaction management with BeginTransaction and custom retry logic if you want to (an API to determine whether errors are safe to retry will be made publicly available).
This is A LOT to consider, isn't it? We're working hard to trying to simplify the API surface of the drivers and we'll hopefully be able to make your lives easier in the 5.x series.
07-26-2022 08:43 AM - edited 07-27-2022 01:53 AM
TO DELETE: initial reply now edited
All the sessions of the conference are now available online