Comments (12)
There really isn't such a thing as an active transaction. _txn
provided storage for transaction data once there is something to store.
Why do you care?
from transaction.
The common technique for handling transactions is with manager:
which will kill any "storage for transaction data" that was previously active. There's currently no supported way to have this with
be a no-op allowing the caller's with
to handle things.
def render_response(request, opts):
user = opts['user']
with transaction.manager: # wish this were either a no-op or at least raised an error
# we could then rewrite this to check for an active transaction first
user.id #-> DetachedInstanceError, its transaction was just closed
return Response()
def handle_request(request):
with transaction.manager:
user = DBSession.query(User).get(1)
render_response(request, dict(user=user))
There is such a thing as an active transaction for anything actually using the transaction package. I realize the package itself doesn't actually manage a physical transaction but it does make it a little harder to support certain use-cases with nested control.
The issue here is that the transaction
package does not support nested transaction scopes like in the example above. BUT it does not yell at you for it, it just happily closes the parent transaction by calling manager.begin()
. This kind of implicit behavior is not ideal. It should either be a no-op to start a nested transaction, leaving the first manager in control or it should raise forcing you to deal with it.
from transaction.
OK, this is an interesting example.
It's not clear why you want the with in render_response
. Given that you are just reading, my guess is that you want to make sure someone has started a transaction recently so you see recent updates. But you don't want to require that the caller has started a transaction. Is that so? And if so, why?
from transaction.
BTW, I'm not trying to argue really, I'm trying to understand your use case.
from transaction.
So in my history of working with transactional databases I've run into and / or wanted to write lots of code in which certain functions may or may not start transactions, allowing them to be reused by other functions that also may or may not want to start transactions. It seemed somewhat common but I've lived for many years now with the transaction package not supporting it. Obviously it's a code smell to have poorly defined division of responsibilities but code hitting the database tends to spider out when you start passing managed objects around.
A more practical example is coming from something like pyramid_tm
where if it's in the pipeline it's going to manage the transaction for you. We've run into countless cases in pyramid where people do database operations before or after pyramid_tm gets control of the transaction. This starts an implicit transaction right now and the user is unaware that they're doing anything wrong. The request then hits pyramid_tm which (silently) closes their transaction and starts a new one invalidating whatever work they had done. We'd like to handle this error-prone case in a better way. At the very least I'd say that raising an exception when calling begin()
twice in a row without an abort()
/commit()
would be good but ideally you could also detect the already-open transaction and start using it, turning the pyramid_tm manager into a no-op.
from transaction.
I like the idea of making begin/end explicit, at least optionally. There's lots of history of implicit transactions where begin and abort were identical or nearly identical, for better or worse. You provide some good use cases.
I'd like to think about this a bit and probably start a discussion in the python-transactions google group.
from transaction.
I think in your nested example from 3 hours ago, you want some way to assert that a transaction has already been started explicitly. Does that sound right?
from transaction.
Yes. There are 2 valid use-cases outside of what transaction currently does (implicit abort if begin is called twice), and there isn't a right answer so I just want them to be possible.
- If a transaction is already active then raise an error or warning.
- If a transaction is already active then start using it instead of calling
.begin()
and avoid calling commit/abort yourself - leave it up to the caller that started the transaction.
Neither of these changes any assumptions about how transaction works, it's just a question of who gets to begin and commit. It's currently possible via manager._txn is None
but I'd just like to see a public api for it.
I'm unaware of that google group but I will join.
from transaction.
manager._txn is very much an internal implementation detail with no intended semantics, so it's well worth avoiding.
from transaction.
"So in my history of working with transactional databases I've run into and / or wanted to write lots of code in which certain functions may or may not start transactions, allowing them to be reused by other functions that also may or may not want to start transactions. It seemed somewhat common"
Can you give an example or 2 of other systems transaction systems that support this pattern?
from transaction.
So thinking about this some more, I think what you really need is to assure that a commit or abort will eventually be called explicitly. It's not the job of library code to decide transaction boundaries, but library code may rely on changes being committed and not being tossed by accident. Does that sound right?
from transaction.
This was added via transaction.get()
in explicit mode which solves my problems (#43). In implicit mode it's natural to expect that you're always in a transaction and thus making the checks irrelevant.
from transaction.
Related Issues (20)
- 3.0.1: pytest warnings HOT 8
- 3.0.1: setuptools build_sphinx command fails HOT 11
- 3.0.1: transaction not sphinx 4.0.x ready? HOT 5
- Print the stack when a resource manager joins a transaction HOT 4
- Question: Nested transaction.manager HOT 2
- Add support for QA tooling? HOT 3
- 3.0.1: sphinx warnings `reference target not found` HOT 1
- Transactions with multiprocessing HOT 2
- Question: How to find a transaction’s data manager, if any? HOT 1
- No status to indicate aborted transaction. HOT 7
- Reach 100% coverage HOT 1
- DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working HOT 2
- 'ThreadTransactionManager' object has no attribute '_retryable' HOT 1
- Support abort hooks (symmetrically to commit hooks) HOT 1
- It's very easy to create reference cycles that require the GC to clean up HOT 9
- Docs: Confusion between resource and data managers HOT 1
- Still possible to join aborted and doomed transactions
- RTD integration broken HOT 2
- Remove legacy functionality from ITransactionDeprecated
- transaction 3.0 breaks afterCommitHooks HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from transaction.