我有一个名为’games’的表,其中包含一个名为’title’的列,此列是唯一的,在Postgresql中使用的数据库
我有一个用户输入表单,允许他在“游戏”表中插入一个新的“游戏”.插入新游戏的功能检查先前输入的具有相同“标题”的’游戏’是否已经存在,为此,我获得了具有相同游戏“标题”的行数.
我为此使用事务,开始时的插入函数使用BEGIN,获取行计数,如果行计数为0,则插入新行,并且在处理完成后,它将COMMITS更改.
问题在于,如果用户同时提交的2个具有相同标题的游戏有可能被插入两次,因为我只是将行数计入chk以获得重复记录,并且每个事务都会彼此隔绝
我想在获取行数时锁定表格为:
LOCK TABLE games IN ACCESS EXCLUSIVE MODE; SELECT count(id) FROM games WHERE games.title = 'new_game_title'
哪个会锁定表进行读取(这意味着其他事务必须等待,直到当前事务成功完成).这将解决问题,这是我怀疑的.有更好的解决方法(避免使用相同标题的重复游戏)
解决方法
使用
highest transaction isolation(Serializable),您可以实现与实际问题类似的功能.但请注意,这可能会失败ERROR:由于并发更新而无法序列化访问
我完全不同意约束方法.您应该有一个约束来保护数据完整性,但依赖约束会强制您不仅识别发生了什么错误,而且识别哪个约束导致了错误.问题不在于如某些人所讨论的那样捕获错误,而是确定导致错误的原因并提供人为可读的失败原因.根据您的应用程序所使用的语言,这几乎是不可能的.例如:告诉用户“游戏标题[foo]已经存在”而不是“游戏必须有价格”用于单独的约束.
INSERT INTO games ( [column1],... ) SELECT [value1],... WHERE NOT EXISTS ( SELECT x FROM games as g2 WHERE games.title = g2.title );
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。