假设我有一个以 user_id 作为主键的映射用户对象,以及一个具有唯一约束的邮件列。我希望我的程序仅在用户表不存在时才将用户对象保存到用户表中。
我可以在我的插入函数中执行以下操作:
- 开始交易
- 使用给定邮件查询用户
- 如果它不存在,创建一个新用户并使用会话保存它
- 如果失败则提交或回滚
有两个问题:
- 执行两个查询很昂贵。如果我使用纯 SQL,我可能会使用“INSERT IGNORE”语法,但在我的情况下,我想使用休眠保存方法,并且我想最后保存用户对象。有解决办法吗?
- 并发。我的应用程序的两个实例是否有可能同时运行。两者都将使用具有相同“mail”参数的“addUser”函数。第一个将经历第 2 阶段,并且找不到使用该邮件的用户。第二个也将通过第 2 阶段而没有找到用户,因为第一个实例仍然没有保存他的用户并提交。然后第一个实例将保存并提交用户,然后第二个实例将保存并提交用户,该用户与第一个实例的邮件具有相同的邮件。当然它会失败,因为约束。我错过了什么吗?
如果我是对的,我应该怎么做:
- 希望它不会发生。
- 在事务开始时锁定用户表以进行读写。
- 将 try...except 添加到函数中,这将排除唯一约束异常,如果抛出异常,将仅根据其邮件从数据库中选择用户。
- 其他解决方案...