0

春のフォーラムにこのメッセージを投稿した男性と同様の問題があります: http://forum.springsource.org/archive/index.php/t-20943.html

基本的に、私は自分が取り組んでいる Web サイトの自動登録機能を書いています。ユーザーの移行元であるサードパーティのデータベースにユーザーが存在し、DB には存在しない場合、ログイン プロセスにより、DB にユーザーが自動的に作成されます。

これを行うには、最初に、ログイン時に電子メールとパスワードを使用してユーザーを認証する必要があります。それが失敗した場合は、サードパーティの DB を確認し、この情報を使用してユーザーを作成しようとします。上記のリンクのように、この存在チェックとそれに続く挿入により、Hibernate によってメソッドがロールバックのみとしてマークされるようです。

存在チェックで Transactional Requires_New を使用して新しいトランザクションに強制しようとしましたが、このトランザクションが親トランザクションではなくロールバックのみとしてマークされることを望んでいましたが、これは機能しませんでした。

誰でもこれを行う方法についてアドバイスできますか? 上記のリンクは、ユーザーが既に存在することを確認するために重複キー エラーを挿入して使用することを提案していますが、これは面倒なようで、大幅な再設計が必要になります。

ところで、Hibernate、Spring、Annotations を使用してトランザクションを処理しています。

4

2 に答える 2

0

私が見つけたこれに対する解決策は、関係するセクションを別々のトランザクションに分割することです。私の場合、ユーザーが存在するかどうかを確認していますが、存在しない場合は、サードパーティのDBで作成しています。これは、認証が失敗した場合、新しいユーザーの作成はロールバックされないことを意味しますが、それが必要な場合は、作成メソッドと認証メソッドが同じトランザクションメソッドにあるように異なる方法で分離できます。

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 に答える
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 に答える