有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java,哪一种更好地抛出异常或提前检查错误

在连接到postgresql的服务器中,是否应该通过执行"select * ..."检查表中是否已经存在用户名,然后获取结果集中的行数,如果行数等于零,则插入用户名
或者在表中插入用户名。如果它已经存在,那么它将抛出一个可以捕获的错误
注意:用户名是主键

做上面两个哪一个更好


共 (6) 个答案

  1. # 1 楼答案

    我更喜欢通过查询检查用户是否存在,而不是使用异常。“用户存在”错误的逻辑可能很快成为业务规则。(您可以用SQL编写这样的规则,但这是完全不同的世界)

    Or just insert the username in the table. If it already exists, then it will throw an error which can then be caught

    问题是有很多其他的例外原因。无论如何,你必须处理好它们

  2. # 2 楼答案

    不应使用异常来控制程序流。如果不是例外情况,最好避免例外

  3. # 3 楼答案

    在这种情况下,答案是两者都不。既不要引起错误,也不要事先检查。嗯,不管怎么说,大部分都是
    它可以处理得更简单,同时更安全、更快:

    INSERT INTO users(username, col1)
    SELECT 'max', 'val1'
    WHERE  NOT EXISTS (SELECT * FROM users WHERE username = 'max')
    

    这将仅在新用户不存在时插入新用户。PostgreSQL将命令状态设置为0 rows affected1 row affected,具体取决于命令是否已经存在。无论哪种方式,它都会在声明之后出现

    如果您想要回复:

    INSERT INTO users(username, col1)
    SELECT 'max', 'val1'
    WHERE  NOT EXISTS (SELECT * FROM users WHERE username = 'max')
    RETURNING username;
    

    仅当用户名不存在时,才会返回该用户名
    但是,该操作不是原子操作,因此如果您有很多并发性,请像下面这样获取表上的锁:

    BEGIN;
    LOCK TABLE users IN SHARE MODE;
    
    INSERT INTO users(username, col1)
    SELECT 'max', 'val1'
    WHERE  NOT EXISTS (SELECT * FROM users WHERE username = 'max')
    RETURNING username;
    
    COMMIT;
    

    请注意,这仍然可能失败,即使可能性很小——例如,如果另一个事务由于某些错误而锁定表并永久阻止您
    因此,不可否认,您仍然需要代码来处理错误情况。除非您的数据库或应用程序出现问题,否则这种情况永远不会发生

  4. # 4 楼答案

    我想说,在这种情况下捕获异常是对异常概念的滥用,如果您可以在之前检查它,您应该检查它

  5. # 5 楼答案

    通常的共识是只对异常情况使用异常,而不是作为控制流构造。在我看来,尝试使用一个碰巧被使用的用户名应该被认为是有效的,而不是不常见的用例

    换句话说,我会先检查现有的用户名

    然而,正如@paxdiablo所指出的,如果您处于多线程环境中,例如web服务器,那么您要么需要添加一些锁定方案,要么无论如何都要使用try/catch方法(考虑到两个线程可能在竞争添加相同的用户名)<然而,这种情况可以肯定地认为是一种例外情况

    相关问题(所有问题的结论都相同,非例外情况下不使用例外):

  6. # 6 楼答案

    您应该使用“try-and-catch-exception”方法,因为您必须这样做

    如果您先检查,则无法阻止某人在您的检查和插入之间为该用户插入一行,在这种情况下,即使您的检查没有找到该用户,该用户仍将在表中

    无法在某种事务中运行check和insert(因此在此期间没有其他人可以插入该用户)。您无法确定非异常是否有效

    尽管许多DBMS提供事务性支持,但我不知道有哪个会锁定您尚未插入的行:-)

    当然,如果您的应用程序设计为只有您的进程才会插入用户(并序列化),那么您可以使用check-first方法。但我会发表大量的评论,大意是如果你扩大规模,它将需要重新审视