4

我对数据库比较陌生。我相信这是经验会回答的问题。

我将 SQLAlchemy 与 PostgreSQL 一起使用。我设置了一个系统,其中分布在多台计算机上的多个进程执行各种任务,然后更新数据库。我在测试中还没有遇到任何事务冲突,但理论上它们仍然是可能的。

根据我在 Google 上找到的信息,看来我要么必须获得数据库锁,要么准备重新启动事务。不幸的是,关于如何实际执行此操作的信息很少。

我假设,要重新启动事务,SQLAlchemy 会抛出一些异常,我的代码必须捕获这些异常,并自行执行重试。如果我违反了唯一性约束,表明我的代码中存在错误而不是事务冲突,那么该异常是否与 SQLA 抛出的异常不同?使用数据库锁会更好吗?

提前致谢!

- 编辑 -

我刚刚了解了“ConcurrentModificationError”。这个名字听起来确实像我正在寻找的例外。文档说它是StaleDataError的别名,它的名字听起来还是对的,但它的文档非常不透明。这是我正在寻找的错误吗?

再次,非常感谢!

4

2 回答 2

2

只需在 khoxsey 的回答中添加一些细节。

如果并发事务相互干扰,将事务隔离级别设置为“可序列化”将使 PostgreSQL 引发错误。当有许多并发数据库连接时,“可序列化”隔离级别会降低性能,但在我的情况下,性能不是问题的足够少。

当事务在此序列化级别上相互冲突时,Postgres 将其称为“序列化错误”,其SQLSTATE 错误代码为“40001”。当前没有驱动程序可移植的方式来访问 SQLAlchemy 中的 SQLSTATE。但是,当使用 psycopg2 驱动程序时,可以通过exc.orig.pgcode访问 SQLSTATE 代码,其中exc是由except语句捕获的异常。

据我所知,异常本身应该是 OperationalError。

于 2012-07-26T00:15:06.710 回答
1

I have not ever seen that error, although the details for StaleModificationError suggest it might be the thing you are concerned about, but there should be no need to lock the entire database. You might read up on transaction isolation in Postgres to prevent the different process workers from unknowingly reading a row being updated in another transaction.

If you set your isolation level higher (read-committed, etc) then your SA session will start collecting locks on the various rows it is touching. You decide for your design how stringent to set the isolation level. You can make it strict enough s your readers will throw an exception when they try to read a row another transaction has locked, and then you can choose to roll back or use the refresh/expire interface to update that particular session.

于 2012-07-24T04:33:03.760 回答