0

我与在春季论坛上发布此消息的人有类似的问题:http: //forum.springsource.org/archive/index.php/t-20943.html

基本上我正在为我工​​作的网站编写自动注册功能。如果用户存在于我们正在从我们的数据库中迁移用户而不是在我们的数据库中的第三方数据库中,那么登录过程将自动在我们的数据库中创建一个用户。

为此,我必须首先尝试使用电子邮件和密码对登录用户进行身份验证。如果失败,我会检查第三方数据库并尝试使用此信息创建用户。如上面的链接所示,似乎这种存在性检查后跟一个插入会导致该方法被 Hibernate 标记为仅回滚。

我曾尝试在存在检查中使用 Transactional Requires_New 来强制它进入一个新的事务,我希望这个事务将被标记为仅回滚而不是父事务,但这没有奏效。

谁能建议如何做到这一点?上面的链接建议插入和使用重复键错误来检查用户是否已经存在,但这看起来很混乱,需要重新设计。

顺便说一句,我们正在使用 Hibernate、Spring 和 Annotations 来处理事务。

4

2 回答 2

0

假设登录方法抛出异常,您可以通过在存在检查方法的 @Transactional 属性中添加 noRollbackFor 选项来修复它。

@Transactional(noRollbackFor=SecuirtyExcepion.class)
public boolean authenticate(String email,String password) throws SecurityException {

}

@Transactional
public void someMethod() {
  try {
   // without noRollbackFor this would result in transaction being marked as 
   // rollback only 
    authenticate(email,password); 

  } catch(SecurityException e) {
    // create user

  }
}
于 2011-10-18T13:30:54.367 回答
0

我发现的解决方案是将相关部分分成单独的事务。在我的情况下,我正在检查用户是否存在,如果不存在,但它在我的第三方数据库中创建它。这意味着如果身份验证失败,那么新用户的创建将不会回滚,但如果需要,它可以不同地分开,因此创建和身份验证方法在同一个事务方法中。

public void login(String username, String password)
{
   User user = null;
   try {
      user = userHelper.findUserByUsername(username);
   } catch (UserNotFoundException e) {
      log.warn(e);
      if (integrationLayer.checkUserExists(username))
      {
         user = userHelper.createUser(username, password);
      }
      else
      {
         return false;
      }
   }

   return userHelper.authenticate(user, password);
}

@Transactional
public User userHelper.findUserByUsername(String Username)
{
   ... find and return user ...
   ... throw user not found exception if not found ...
}

@Transactional
public User userHelper.createUser(String Username, String Password)
{
   ... create and return the new user ...
}


@Transactional
public Boolean userHelper.authenticate(String Username, String Password)
{
   ... authenticate the user ...
}

@Transactional
public Boolean integrationLayer.checkUserExists(String username)
{
   ... if the user exists in the third party DB return true ...
}
于 2011-10-20T11:00:47.933 回答