2016-04-06 16 views
0

同じサービスの他のトランザクションメソッドを呼び出す非トランザクション非同期メソッドがあります。別のトランザクションメソッドを呼び出す非同期メソッドのロールバック

何か問題が発生した場合、例外が発生した場合、エラーは保存されますが、ロールバックは機能しません。

この例では、Playerサービスのメソッドを呼び出すために、トランザクションはプレーヤを保存します。

@Service 
@Transactional(readOnly = true) 
public class PlayerServiceImpl implements PlayerService { 

    @Inject 
    PlayerRepository playerRepository; 

    @Override 
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED) 
    public void save(PlayerEntity player) { 
     //more code here 
     playerRepository.save(player); 
    } 

    //other methods 
} 

私の他のサービス:

@Service 
    public class TeamServiceImpl implements TeamService { 

     @Inject 
     TeamRepository teamRepository; 

     @Inject 
     MessageRepository messageRepository; 

     @Inject 
     ErrorRepository errorRepository;  

     @Inject 
     PlayerService playerService;  


     @Async("asyncExecutor") 
     @Override 
     public void saveWithPlayersAsync(TeamEntity team, User user) { 

      MessageEntity message = new MessageEntity(); 

      try { 

    //I want rollback this if something wrong happens 
       this.savePlayersA(team); 
       this.savePlayersB(team); 
       message.setContent("Ok !"); 
      } catch (TeamException e) { 
       //e.printStackTrace(); 
       message.setContent("Fail !");   
       message.setUser(user) 
//I save the error for audit 
       errorRepository.save(new Error("Fail", user.getCode())); 
      } finally { 
//always save message for user than execute de function 
       messageRepository.save(message); 
      } 

     } 

     @Transactional(readOnly = false, rollbackFor = TeamException.class) 
     private void savePlayersA(TeamEntity team) throws TeamException { 
      PlayerEntity p1 = new PlayerEntity(); 
      p1.setName("Name 1"); 
      p1.setSurname("Surname 1"); 
      p1.setTeam(team); 
      playerService.save(p1); 

      PlayerEntity p2 = new PlayerEntity(); 
      p2.setName("Name 2"); 
      p2.setSurname("Surname 2"); 
      p2.setTeam(team); 
      playerService.save(p2); 
     } 

     @Transactional(readOnly = false, rollbackFor = TeamException.class) 
     private void savePlayersB(TeamEntity team) throws TeamException { 
      PlayerEntity p3 = new PlayerEntity(); 
      p3.setName("Name 3"); 
      p3.setSurname("Surname 3"); 
      p3.setTeam(team); 
      playerService.save(p3); 

      PlayerEntity p4 = new PlayerEntity(); 
      p4.setName("Name 4"); 
      p4.setSurname("Surname 4"); 
      p4.setTeam(team); 
      playerService.save(p4); 

      // here something happens and throw my custom exception 
      if (true) { 
       throw new TeamException("Fail!"); 
      } 
     } 
    } 

しないのはなぜロールバック?私は例外の型をrollbackForに入れます。

答えて

0

これはロールバックされない理由は、トランザクションメソッドを呼び出す非同期メソッドが同じクラスにあるためです。 @Transactionまたは@Asyncでメソッドに注釈を付けると、注釈コードはSpringによって作成されたプロキシによって処理されます。注釈付きのメソッドが同じクラスにある場合、その呼び出しは、春から追加の要求を処理するためにプロキシによってキャプチャされることができないため、メソッドの注釈は冗長です。 savePlayerメソッドを別のクラスに入れ、そこにメソッドtransactionalを持たせることで、これを得ることができます。

関連する問題