实现用户登录,JDBC事务问题

时间:2011-02-25 14:59:49

标签: java database jdbc transactions

我对数据库交易有疑问,我不确定我的理解是否正确。我想在java应用程序中实现用户登录。由于可能有多个服务器作用于同一个数据库,并且每个用户只能登录其中一个服务器,因此如果用户已经登录,则数据库必须存储标志。

假设有以下表结构:

ID | User | PWD | Server

其中Server是用户登录到的服务器的引用,如果他没有登录则为NULL

当用户登录时,我必须首先检查服务器值是否为NULL,如果不是,则将其设置为Corresponig参考值。但是,当这两个语句之间用户登录另一台服务器时会发生什么?交易可以检测到这种情况吗?例如(伪)

conn.setAutoCommit(false);
ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM users WHERE user = 'usr' AND password = 'pwd'");
if (rs.next()) {
  rs.getInt("Server");
  if (rs.wasNull()) {
    // Not logged in
    conn.createStatement().execute("UPDATE users SET server = 123 WHERE user = 'usr' AND password = 'pwd'");
    conn.commit();
  }
} else {
  // Usr/Pwd wrong
}
conn.rollback();

如果用户在另一台服务器上的select和update语句之间登录,会发生什么?提交失败,因为在交易过程中表被其他人更改了,或者它是否仍在执行?

我应该更好地使用像

这样的方法
UPDATE users SET server = 123 WHERE user = 'usr' AND pwd = 'pwd' AND server IS NULL

并检查0行是否受到影响?如果是这样,我必须检查用户是否存在于查询中。

使用INSERT注册新用户时会出现Simmilar问题。 Shoud我使用事务方法,或者将用户列声明为UNIQUE并捕获SQL异常?

2 个答案:

答案 0 :(得分:2)

使用您对伪代码建议的事务将解决此问题,但请确保将事务隔离级别设置为TRANSACTION_REPEATABLE_READ。有关详细信息,请参阅此tutorial

你还需要思考:

  • 从不,永远不会将纯文本密码存储在数据库中。您需要使用单向哈希。另外,请务必注意散列算法和实现。搜索“HBGary”和“Anonymous”以了解如果不这样做可能会发生什么。
  • 想想如果用户登录到一台服务器会发生什么,并且客户端在他有机会注销之前崩溃。

答案 1 :(得分:0)

在更新用户行的情况下,您可以指定锁定该特定行,以便其他任何jdbc连接都不能修改它。