[英]Do I need to use transactions in google appengine
update 0 My def post()
code has changed dramatically because originally it was base on a digital form which included both checkboxes and text entry fields, not just text entry fields, which is the current design to be more paper-like. 更新0我的
def post()
代码发生了巨大变化,因为它最初是基于数字形式的,它既包含复选框又包含文本输入字段,而不仅仅是文本输入字段,而当前的设计更像纸张。 However, as a result I have other problems which may be solved by one of the proposed solutions, but I cannot exactly follow that proposed solution, so let me try to explain new design and the problems. 但是,结果,我还有一个其他问题可以通过建议的解决方案之一解决,但是我不能完全遵循该建议的解决方案,所以让我尝试解释一下新的设计和问题。
The smaller problem is the inefficiency of my implementation because in the def post()
I create a distinct name
for each input timeslot which is a long string <courtname><timeslotstarthour><timeslotstartminute>
. 较小的问题是我的实现效率低下,因为在
def post()
我为每个输入时隙创建了一个不同的name
,该name
是一个长字符串<courtname><timeslotstarthour><timeslotstartminute>
。 In my code this name
is read in a nested for
loop with the following snippet [very inefficient, I imagine]. 在我的代码中,此
name
是在嵌套的for
循环中读取的,其中包含以下代码段(我想这效率很低)。
tempreservation=courtname+str(time[0])+str(time[1])
name = self.request.get('tempreservation',None)
The more serious immediate problem is that my def post()
code is never read and I cannot figure out why (and maybe it wasn't being read before, either, but I had not tested that far). 更为严重的紧迫问题是,我的
def post()
代码从未被读取,而且我也无法弄清楚为什么(也许以前也没有被读取,但是我还没有进行过如此广泛的测试)。 I wonder if the problem is that for now I want both the post and the get to "finish" the same way. 我想知道问题是否在于现在我是否希望职位和职位都以相同的方式“完成”。 The first line below is for the post() and the second is for the get().
下面的第一行用于post(),第二行用于get()。
return webapp2.redirect("/read/%s" % location_id)
self.render_template('read.html', {'courts': courts,'location': location, ... etc ...}
My new post() is as follows. 我的新post()如下。 Notice I have left in the code the
logging.info
to see if I ever get there. 注意,我在代码中保留了
logging.info
以查看是否到达那里。
class MainPageCourt(BaseHandler):
def post(self, location_id):
logging.info("in MainPageCourt post ")
startTime = self.request.get('startTime')
endTime = self.request.get('endTime')
day = self.request.get('day')
weekday = self.request.get('weekday')
nowweekday = self.request.get('nowweekday')
year = self.request.get('year')
month = self.request.get('month')
nowmonth = self.request.get('nowmonth')
courtnames = self.request.get_all('court')
for c in courtnames:
logging.info("courtname: %s " % c)
times=intervals(startTime,endTime)
for courtname in courtnames:
for time in times:
tempreservation=courtname+str(time[0])+str(time[1])
name = self.request.get('tempreservation',None)
if name:
iden = courtname
court = db.Key.from_path('Locations',location_id,'Courts', iden)
reservation = Reservations(parent=court)
reservation.name = name
reservation.starttime = time
reservation.year = year
reservation.nowmonth = int(nowmonth)
reservation.day = int(day)
reservation.nowweekday = int(nowweekday)
reservation.put()
return webapp2.redirect("/read/%s" % location_id)
Eventually I want to add checking/validating to the above get() code by comparing the existing Reservations data in the datastore with the implied new reservations, and kick out to an alert which tells the user of any potential problems which she can address. 最终,我想通过将数据存储区中的现有Reservations数据与隐含的新保留进行比较,来对上述get()代码进行检查/验证,并踢出一个警报,告知用户她可以解决的任何潜在问题。
I would also appreciate any comments on these two problems. 对于这两个问题的任何评论,我也将不胜感激。
end of update 0 更新结束0
My app is for a community tennis court. 我的应用程序用于社区网球场。 I want to replace the paper sign up sheet with an online digital sheet that mimics a paper sheet.
我想用模拟纸页的在线数字纸代替纸注册纸。 As unlikely as it seems there may be "transactional" conflicts where two tennis appointments collide.
看起来不太可能发生两次网球约会相撞的“交易”冲突。 So how do I give the second appointment maker a heads up to the conflict but also give the successful party the opportunity to alter her appointment like she would on paper (with an eraser).
因此,我该如何让第二位约会制作者直面冲突,又如何让成功的聚会有机会像在纸上(用橡皮擦)那样更改约会。
Each half hour is a time slot on the form. 每半小时是表格上的一个时隙。 People normally sign up for multiple half hours at one time before "submitting".
人们通常在“提交”之前一次注册多个半小时。
So in my code within a loop I do a get_all. 因此,在循环代码中,我执行了get_all。 If any get succeeds I want to give the user control over whether to accept the put() or not.
如果任何获取成功,我想让用户控制是否接受put()。 I am still thinking the put() would be an all or nothing, not selective.
我仍然认为put()是全有还是全无,不是选择性的。
So my question is, do I need to make part of the code use an explicit "transaction"? 所以我的问题是,我是否需要使代码的一部分使用显式的“事务”?
class MainPageCourt(BaseHandler):
def post(self, location_id):
reservations = self.request.get_all('reservations')
day = self.request.get('day')
weekday = self.request.get('weekday')
nowweekday = self.request.get('nowweekday')
year = self.request.get('year')
month = self.request.get('month')
nowmonth = self.request.get('nowmonth')
if not reservations:
for r in reservations:
r=r.split()
iden = r[0]
temp = iden+' '+r[1]+' '+r[2]
court = db.Key.from_path('Locations',location_id,'Courts', iden)
reservation = Reservations(parent=court)
reservation.starttime = [int(r[1]),int(r[2])]
reservation.year = int(r[3])
reservation.nowmonth = int(r[4])
reservation.day = int(r[5])
reservation.nowweekday = int(nowweekday)
reservation.name = self.request.get(temp)
reservation.put()
return webapp2.redirect("/read/%s" % location_id)
else:
... this important code is not written, pending ...
return webapp2.redirect("/adjust/%s" % location_id)
You can check for the availability of the time slots in a given Court
, and write the corresponding Reservations
child entities only if their stat_time
don't conflict. 您可以检查给定
Court
时隙的可用性,并仅在其stat_time
不冲突时编写相应的Reservations
子实体。
Here is how you would do it for 1 single reservation using a ancestor Query: 这是使用祖先查询进行1次单个预订的方法:
@ndb.transactional
def make_reservation(court_id, start_time):
court = Court(id=court_id)
existing = Reservation.query(Reservation.start_time == start_time,
ancestor=court.key).fetch(2, keys_only=True)
if len(existing):
return False, existing[0]
return True, Reservation(start_time=start_time, parent=court.key).put()
Alternativly, if you make the slot part of the Reservation id, you can remove the query and construct the Reservation entity keys to check if they already exists: 或者,如果将插槽作为保留标识的一部分,则可以删除查询并构造保留实体键以检查它们是否已存在:
@ndb.transactional
def make_reservations(court_id, slots):
court = Court(id=court_id)
rs = [Reservation(id=s, parent=court.key) for s in slots]
existing = ndb.get_multi(r.key for r in rs)
if any(existing):
return False, existing
return True, ndb.put_multi(rs)
I think you should always use transactions, but I don't think your concerns are best addressed by transactions. 我认为您应该始终使用事务,但是我认为事务不能最好地解决您的顾虑。
I think you should implement a two-stage reservation system - which is what you see on most shopping bags and ticketing companies. 我认为您应该实施两阶段的预订系统-这是大多数购物袋和票务公司所看到的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.