Invalid transaction persisting across requests

后端 未结 2 799
盖世英雄少女心
盖世英雄少女心 2020-12-23 20:17

Summary

One of our threads in production hit an error and is now producing InvalidRequestError: This session is in \'prepared\' state; no further SQL can be

2条回答
  •  春和景丽
    2020-12-23 20:43

    A surprising thing is that there's no exception handling around that self.session.commit. And a commit can fail, for example if the connection to the DB is lost. So the commit fails, session is not removed and next time that particular thread handles a request it still tries to use that now-invalid session.

    Unfortunately, Flask-SQLAlchemy doesn't offer any clean possibility to have your own teardown function. One way would be to have the SQLALCHEMY_COMMIT_ON_TEARDOWN set to False and then writing your own teardown function.

    It should look like this:

    @app.teardown_appcontext
    def shutdown_session(response_or_exc):
        try: 
            if response_or_exc is None:
                sqla.session.commit()
        finally:
            sqla.session.remove()
        return response_or_exc
    

    Now, you will still have your failing commits, and you'll have to investigate that separately... But at least your thread should recover.

提交回复
热议问题