A lesson of @Transactional


Recently, I needed to work with a Cursor for statistics.

<mapper ...>
  <select id="selectCorsor" resultOrdered="true">
  </select>
</mapper>

It didn’t make any difference.

@Mapper
public interface SomeMapper {
    Cursor<Some> selectCursor(...);
}

We need the @Transactional annotation for working with Cursor.

@Service
public class SomeService {

    @Transactional
    public <R> R applyCursor(
            ...,
            final Function<Cursor<Some>, R> function) {
         return function.apply(someMapper.selectCursor(..));
    }

    @Autowired
    private SomeMapper someMapper;
}

Well the method worked as expected.

The problem arose when I added a method using the origin method.

    public void acceptEach(
            ...,
            final Consumer<Some> consumer) {
        applyCursor(
            ...,
            cursor -> {
                cursor.forEach(consumer::accept);
                return null;
            }
        );
    }

This auxiliary method was not annotated with @Transactional and it didn’t work.

And I found @Transactional method calling another method without @Transactional anotation?.

The acceptEach method was also required to be annotated with @Transactional​.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s