【发布时间】:2013-07-07 05:19:09
【问题描述】:
这是我的情况。
我正在构建一个 RESTful 网络服务,它从客户端接收数据,然后从该数据创建一个事件,然后我想将此新事件推送到 celery 以异步处理它。
我使用 pyramid 来构建 RESTful 网络服务,并使用 pyramid_celery 使金字塔和 celery 协同工作。
这是我的观点的源代码:
# views.py
# This code recive data from client, then create a new record Event from this
posted_data = schema.deserialize(request.POST.mixed())
e = Event()
e.__dict__.update(posted_data)
DBSession.add(e)
transaction.commit()
print "Commited #%d" % e.id # code mark 01
fire_event.delay(e.id) # fire_event is a celery task
logging.getLogger(__name__).info('Add event #%d to tasks' % e.id)
这是我的任务的源代码:
# tasks.py
@celery.task()
def fire_event(event_id):
e = DBSession.query(Event).get(event_id)
if e is None:
return
print "Firing event %d#%s" % (event_id, e)
logger.info("Firing event %d#%s", event_id, e)
如果我使用来自金字塔炼金术脚手架的默认代码,则会在 code mark 01 行引发异常。像这样的例外:
DetachedInstanceError: Instance <Event at ...> is not bound to a Session; ...
来自ZopeAlchemy document,为避免此异常,我这样配置 DBSession:
# models.py
DBSession = scoped_session(sessionmaker(
extension=ZopeTransactionExtension(keep_session=True)
))
现在我的问题是我的 RESTful 请求完成后与我的 MySQL 服务器的金字塔保持事务。当 RESTful 请求完成后,我转到 MySQL 服务器并运行命令:
SHOW engine innodb status;
从结果中,我看到了:
--TRANSACTION 180692, ACTIVE 84 sec
MySQL thread id 94, OS thread handle 0x14dc, query id 1219 [domain] [ip] [project name] cleaning up
Trx read view will not see trx with id >= 180693, sees < 180693
这意味着 Pyramid 仍然保持连接,没关系,但 Pyramid 也开始事务,这是一个问题。当我尝试使用其他工具访问我的 MySQL 服务器时,此事务可能使我处于锁定状态。
我的问题是:
如何让 Pyramid 在 RESTful 请求完成后立即关闭事务。如果不能,是否有针对我的情况的其他解决方案?
非常感谢。
【问题讨论】:
标签: transactions celery pyramid