【发布时间】:2014-01-14 09:20:40
【问题描述】:
我在多进程环境中遇到了一个奇怪的行为。
我的第一个进程(后来称为 P1)通过 sqa 写入 db。我的第二个进程(后来称为 P2)通过 sqa 从 db 读取。第二个进程是一个 Web 应用程序,它通过 ajax 调用请求最新数据。
当 P1 更新数据(写入)时,P2 不会立即看到更改(读取)。在实际看到数据库更改(issuing session.query(...)) 之前,它必须轮询几次。如果我运行另一个 P3 进程,我可以看到更改实际上是在 db 中完成的,但 P2(网络应用程序)不会立即看到它。
我在 Ubuntu 13.04 上运行 sqa 0.8.4 (underlying db: sqlite),我的网络应用基于 cherrypy framework (3.2.0)
我使用作用域会话来获取线程安全的会话对象,如 SQLAlchemy documentation
这是我所有进程都使用的 OrmManager 类:
class OrmManager:
def __init__(self, database, metadata, echo=False):
self.database = database
engine = create_engine('sqlite:///' + database,
echo=echo,
connect_args={'detect_types': sqlite3.PARSE_DECLTYPES|
sqlite3.PARSE_COLNAMES},
native_datetime=True,
poolclass=NullPool,
convert_unicode=True
)
metadata.create_all(engine)
# this factory is thread safe: a session object is returned (always the same) to the
# caller. If called from another thread, the returned session object will be different
session_factory = sessionmaker(bind=engine, expire_on_commit=False)
self.session = scoped_session(session_factory)
def get_session(self):
session = self.session()
return session
P1、P2 和 P3 实现 OrmManager 并使用返回的会话如下:
orm_mgr = OrmManager(database=<path/to/my/.sqlite/file>, metadata=METADATA)
session = orm_mgr.get_session()
# do some stuff here
session.commit()
我检查了 P1 代码。 (call to session.commit()) 已很好地提交了 db 更改,但与 P3 (cmd line process) 相比,P2 (web app) 无法实时看到更改。 P2 可能需要几秒钟才能获得更改...
有什么想法吗?
非常感谢,
皮埃尔
【问题讨论】:
标签: python sqlite sqlalchemy cherrypy