Spring, JPA e Hibernate: cómo incrementar un contador sin problemas de concurrencia

Estoy jugando un poco con Spring y JPA / Hibernate y estoy un poco confundido sobre la forma correcta de incrementar un contador en una mesa.

Mi API REST necesita aumentar y disminuir algún valor en la base de datos dependiendo de la acción del usuario (en el ejemplo siguiente, si le gusta o no una etiqueta, el contador aumentará o disminuirá en uno en la Tabla de etiquetas)

tagRepository es unJpaRepository (Spring-data) y he configurado la transacción de esta manera

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"/>

@Controller
public class TestController {

    @Autowired
    TagService tagService

    public void increaseTag() {
        tagService.increaseT,agcount();
    }
    public void decreaseTag() {
        tagService.decreaseTagcount();

    }
}

@Transactional
@Service
public class TagServiceImpl implements TagService {


    public void decreaseTagcount() {
        Tag tag = tagRepository.findOne(tagId);
        decrement(tag)
    }

    public void increaseTagcount() {
        Tag tag = tagRepository.findOne(tagId);
        increment(tag)
    }

    private void increment(Tag tag) {
        tag.setCount(tag.getCount() + 1); 
        Thread.sleep(20000);
        tagRepository.save(tag);
    }

    private void decrement(Tag tag) {
        tag.setCount(tag.getCount() - 1); 
        tagRepository.save(tag);
    }
}

Como puede ver, he puesto un sueño de 20 segundos en incrementos JUSTO antes del.save() para poder probar un escenario de concurrencia.

contador de etiqueta inicial = 10;

1) Un usuario llama al aumento de etiqueta y el código llega al modo de suspensión, por lo que el valor de la entidad = 11 y el valor en la base de datos sigue siendo 10

2) un usuario llama a la etiqueta disminuir y revisa todo el código. el valor es la base de datos es ahora = 9

3) El sueño finaliza y golpea el .save con la entidad contando 11 y luego golpea .save ()

Cuando reviso la base de datos, el valor de esa etiqueta ahora es igual a 11 .. cuando en realidad (al menos lo que me gustaría lograr) sería igual a 10

¿Es este comportamiento normal? O la@Transactional anotación no está haciendo es trabajo?

Respuestas a la pregunta(2)

Su respuesta a la pregunta