2009-02-21 104 views
4

我已经做了一些与sqlite并发问题有关的阅读,但我没有看到它们如何应用到Django,因为它本质上是单线程的。我没有使用任何多进程模块。我对于并发编程绝对没有经验,所以如果有人能够确定为什么下面的代码导致OperationalError:'数据库被锁定',我将不胜感激。Django和Sqlite并发问题

views.py

def screening(request, ovramt=None): 
errors = [] 
if request.method == "POST": 
    form = ScreeningForm(request.POST) 
    if form.is_valid(): 
     print "Woo valid!!" 
    return HttpResponse() 

else: # GET    
    if ovramt is None: 
     o = Ovramt.objects.select_related(depth=1).latest("date_completed") 
     print "found?" 
     print o.id 
    else: 
     try: 
      o = Ovramt.objects.select_related(depth=1).get(id=ovramt) 
     except: 
      errors.append("OVRAMT NOT FOUND") 


    if o.residents.count() <= 0: 
     o.add_active_residents() 
    residents = list(o.residents) 

models.py

def add_active_residents(self): 
    ssa_res = SSA_Resident.objects.select_related(depth=1).filter(ssa=self.ssa, active=True) 
    for r in ssa_res: 
     self.residents.add(r.resident) # Fails Here 
    self.save() 

的add_active_residents方法工作得很好,直到它从视图模块调用。在视图中打开的数据库是否有开放连接,防止从模型中写入数据?有人解释为什么这段代码会出错吗?

+0

因此,每次您在视图中调用add_active_residents时都会发生锁定?什么确切的线是抛出锁异常(保存?)它是否发生在devserver中,或仅在生产环境中? – 2009-02-21 14:41:43

+0

这发生在devserver中,只有当视图调用add_active_residents时才会发生。从命令行调用add_active_residents不会出错。 – 2009-02-22 03:26:15

回答

4

在下面的方法函数

def add_active_residents(self): 
    ssa_res = SSA_Resident.objects.select_related(depth=1).filter(ssa=self.ssa, active=True) 
    for r in ssa_res: 
     self.residents.add(r.resident) # Fails Here 
    self.save() 

为什么会出现一个select_related?你只需要ssa_res项目的FK。为什么要对相关项目进行额外查询?

+0

SSA_Resident是SSA和Resident之间的Many2Many表,其中包含驻留和ssa对象。我假设这些对象需要被返回,以便将它们添加到Ovramt_Resident的许多关系中。 – 2009-02-21 03:28:29

1

听起来就像你实际上在运行多线程应用程序,尽管你说了什么。我对Django有点无知,但我认为即使它可能是单线程的,无论您在哪个调试服务器或生产服务器上运行应用程序,都不会“天生就是单线程的”。

2

你使用Python 2.6吗?

如果是这样,这是(显然)一个已知的问题,可以通过增加来缓解:

DATABASE_OPTIONS = {'timeout': 30} 

您settings.py

http://code.djangoproject.com/ticket/9409

2

我的理解是,只写操作将导致db-locked情况。 http://www.sqlite.org/lockingv3.html

如果不知道django如何在内部处理sqlite,很难说出问题所在。

从使用sqlite和标准cgi说起,我注意到在某些情况下,释放锁可能需要很长时间。你可能想要增加Matthew Christensen提到的超时值。