Search code examples
javaspringdatabasemybatisspring-transactions

Is @Transactional necessary for multiple query operations in one method using MyBatis?


I'm currently working with MyBatis and I have a method where I perform multiple query operations. For example, in my UserService class, I have a method getUserOrders(String username) where I first fetch the user based on the username and then fetch their orders:

public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrderMapper orderMapper;

    public List<Order> getUserOrders(String username) {
        User user = userMapper.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User not found: " + username);
        }

        return orderMapper.findByUserId(user.getId());
    }
}

I'm wondering if adding @Transactional(readOnly = true) to this method would ensure that both queries are executed on the same database connection? If so, does this mean that without this annotation, each query could potentially use a different database connection? Moreover, what would be the implications if these queries were part of different transactions? For example,another query doesn't see if there are other concurrent transactions modifying the data.

And how does setting readOnly = true affect this scenario?When querying, whether the read-only attribute should be added to the transaction annotation.

I understand that @Transactional is generally used for write operations to ensure atomicity. But how does it apply to read-only operations like in my example?


Solution

  • I understand that @Transactional is generally used for write operations to ensure atomicity. But how does it apply to read-only operations like in my example?

    Read-only operations are managed by transactions. You should put @Trandactional(readOnly) annotation on the class, so you don't need to use it on every method that uses a database. It should also have a @Service annotation to use with Spring context.

    @Service
    @Transactional(readOnly = true)
    public class UserService {
    }