Thanks Michael. Always spot on. And I don't think I can find a more
authoritative source ;)


On Wed, Dec 19, 2012 at 5:48 PM, Michael Bayer <[email protected]>wrote:

>
> On Dec 19, 2012, at 4:29 AM, charlax wrote:
>
>
> So the problem here is that the rollback does nothing, because there's a
> commit in the delete_password method (in this example there's only method
> called, in reality I have multiple methods). I think having stuff being
> committed in a model's method is antipattern (is it?)
>
>
> I think it is.  I wish I could find more authoritative sources for this
> but in my opinion, as well as all the experience I've had with
> transaction-aware frameworks, transaction demarcation is specified in the
> application in exactly one place, in a position that surrounds all the
> business logic.  The business logic itself should not have any awareness of
> transaction demarcation.
>
> I've updated the docs significantly to talk about this pattern here:
> http://docs.sqlalchemy.org/en/rel_0_8/orm/session.html#session-frequently-asked-questions,
> in the question "when do I construct a Session?".    Web frameworks present
> the simplest pattern, but if your application is not a web application,
> you'd want to decide on where your app's concept of "business methods" can
> be enclosed.
>
>
> but I'd like to know if there's a simple way to get the desired behavior.
> I tried:
>
>
>
>    1. Manually setting a savepoint (Session.execute("SAVEPOINT
>    soft_delete")). But commit in delete_password closes the connection so
>    the savepoint is lost.
>    2. Using begin_nested and begin(subtransactions=True), but commit in
>    delete_password closes the context
>
>
>    1. I thought of using autocommit=True but it seems it's not
>    recommended (and I'm not sure to understand all the implications of this),
>    or creating an external 
> transaction<http://docs.sqlalchemy.org/en/latest/orm/session.html#joining-a-session-into-an-external-transaction>
>  but
>    the example in the doc is only for tests so I'm not sure if it's
>    antipattern too. Also, getting access to the engine would require quite a
>    small refactor of my app.
>
>
> the subtransaction thing could allow this, if your ad-hoc commit() method
> also called begin(subtransactions=True) before it did its work, but this
> implies the Session is being used in autocommit mode.
>
> But there's no reason to use autocommit, while it used to be the default
> system of use years ago, now it's only there for certain framework
> integrations that want to be able to emit begin() ahead of time.  The
> Session otherwise shouldn't be used to emit SQL without a transaction
> present.
>
> Which means, there's really no reason in the world you need to call
> commit() inside that method, *unless* you're trying to expose that
> particular bit of data to the outside world before the enclosing
> transaction is complete - and for that use case I'd use a different
> transaction altogether.   Otherwise, you're already in a transaction that
> isn't yet committed, which your app structure should ensure happens before
> the larger series of business methods is complete.
>
>  --
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/sqlalchemy?hl=en.
>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to