我们正在使用Django 1.3。我们的模型是:
class Info(models.Model):
class Meta:
ordering = ('-ts','snp_number',)
ts = models.DateTimeField(auto_now_add = True)
description = models.TextField()
release = models.CharField(max_length=50)
stream = models.CharField(max_length=100)
class Snap(models.Model):
class Meta:
ordering = ('-snp',)
unique_together = ('snp','app_name')
snp = models.ForeignKey(SnapInfo)
app_name = models.CharField(max_length=255)
parent_app_name = models.CharField(max_length=255)
class Env(models.Model):
class Meta:
ordering = ('-snp',)
snp = models.ForeignKey(Snap)
env = models.CharField(max_length=50)
class Connection(models.Model):
class Meta:
ordering = ('-snp',)
snp = models.ForeignKey(Snap)
app_name = models.CharField(max_length=255)
对于给定的Info
,我们可以有多个Snap
。对于给定的Snap
,我们可以有多个Connection
和Env
。
写
在我们的应用程序的某个地方,我们在
创建了快照@transaction.commit_on_success
def create_snap_controller (topo_id=None, release=None, type=PREP, is_live=False):
try:
snp_info = Info.get_or_create_snap(release_name, type)
except Exception as e:
log.error("%s - Error creating snap Info for the release %s and type %s " %(str(e), release_name, type))
...
return create_snap(snp_info, app_name, parent_name)
def create_snap(info, app_name, parent_name):
...
snp = Snap.objects.create(snp=info, app_name=app_name, parent_app_name=parent_name)
for conn in connections:
conn = Connection.objects.create(snp=snp, app_name=conn)
for env in envs:
create_env(snp, env)
...
return snp
def create_env(snp, env):
....
e = Env.objects.create(snp=snp, env=env)
阅读
还有一个API可以读取这些最新的Snap
和给定的app_name
,并返回自身的JSON以及所有关联的Env
和Connection
。
并发问题
问题有时是API返回部分数据,因为提交未完成。也就是说,当API在提交进行时,它会返回部分最新信息。
我们希望使插入成为原子,以便通过API进行的读取不包含部分信息。
到目前为止的努力
select_for_update
(从1.4开始)似乎锁定行但不保证原子性。 transaction.commit_on_success
也不能确保原子性。我该怎么做?