Spring @Transaction method call by the method within the same class, does not work?

前端 未结 8 2191
谎友^
谎友^ 2020-11-22 05:07

I am new to Spring Transaction. Something that I found really odd, probably I did understand this properly.

I wanted to have a transactional around method level and

相关标签:
8条回答
  • 2020-11-22 05:49

    With Spring 4 it's possible to Self autowired

    @Service
    @Transactional
    public class UserServiceImpl implements UserService{
        @Autowired
        private  UserRepository repository;
    
        @Autowired
        private UserService userService;
    
        @Override
        public void update(int id){
           repository.findOne(id).setName("ffffd");
        }
    
        @Override
        public void save(Users user) {
            repository.save(user);
            userService.update(1);
        }
    }
    
    0 讨论(0)
  • 2020-11-22 05:56

    Starting from Java 8 there's another possibility, which I prefer for the reasons given below:

    @Service
    public class UserService {
    
        @Autowired
        private TransactionHandler transactionHandler;
    
        public boolean addUsers(List<User> users) {
            for (User user : users) {
                transactionHandler.runInTransaction(() -> addUser(user.getUsername, user.getPassword));
            }
        }
    
        private boolean addUser(String username, String password) {
            // TODO call userRepository
        }
    }
    
    @Service
    public class TransactionHandler {
    
        @Transactional(propagation = Propagation.REQUIRED)
        public <T> T runInTransaction(Supplier<T> supplier) {
            return supplier.get();
        }
    
        @Transactional(propagation = Propagation.REQUIRES_NEW)
        public <T> T runInNewTransaction(Supplier<T> supplier) {
            return supplier.get();
        }
    }
    

    This approach has the following advantages:

    1. It may be applied to private methods. So you don't have to break encapsulation by making a method public just to satisfy Spring limitations.

    2. Same method may be called within different transaction propagation and it is up to the caller to choose the suitable one. Compare these 2 lines:

      transactionHandler.runInTransaction(() -> userService.addUser(user.getUserName, user.getPassword)); transactionHandler.runInNewTransaction(() -> userService.addUser(user.getUserName, user.getPassword));

    3. It is explicit, thus more readable.

    0 讨论(0)
提交回复
热议问题