2016-10-19 2 views
0

Je suis nouveau à springboot et je le considère pour un nouveau projet. Tout en testant ses capacités, je continue à ne pas utiliser l'annotation @Transactional.SpringBoot @ Le rollback transactionnel ne fonctionne pas

J'ai fait une petite base de données MySql auquel je me connecte définition de cette application.properties fichier:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver 
spring.datasource.url=jdbc:mysql://127.0.0.1:3311/mb 
spring.datasource.username=mb 
spring.datasource.password=password 
spring.datasource.tomcat.default-auto-commit=false 

est un peu Ci-dessous la classe que j'utilise pour accéder à la base de données. Dans la méthode insertUser (...), j'ai intentionnellement répété l'instruction d'insertion afin que la deuxième instruction d'insertion entraîne une annulation en raison d'une entrée en double sur la clé primaire de la table.

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.jdbc.core.JdbcTemplate; 
import org.springframework.jdbc.core.RowMapper; 
import org.springframework.stereotype.Repository; 
import org.springframework.transaction.annotation.Transactional; 
import org.springframework.util.ObjectUtils; 
import org.springframework.util.StringUtils; 

import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.util.List; 

@Repository 
@Transactional 
public class UserRepository { 
    protected final Logger log = LoggerFactory.getLogger(getClass()); 

    @Autowired 
    protected JdbcTemplate jdbc; 


    public User getUser(long id) { 
     return jdbc.queryForObject("SELECT * FROM test_table WHERE id=?", userMapper, id); 
    } 

    public List<User> getUsers(long[] ids) { 
     String inIds = StringUtils.arrayToCommaDelimitedString(ObjectUtils.toObjectArray(ids)); 
     List<User> u= jdbc.query("SELECT * FROM test_table WHERE id IN (" + inIds + ")", userMapper); 
     return u; 
    } 

    @Transactional 
    public int insertUser(User u) { 

     int total = jdbc.update("insert into test_table values ('"+u.id+"', '"+u.firstname+"', 'toto', '"+u.email+"', NOW())"); 
     //second insert that will cause an exception due to a duplicate key on PK (first column) 
     total += jdbc.update("insert into test_table values ('"+u.id+"', '"+u.firstname+"', 'toto', '"+u.email+"', NOW())"); 
     return total; 
    } 

    private static final RowMapper<User> userMapper = new RowMapper<User>() { 
     public User mapRow(ResultSet rs, int rowNum) throws SQLException { 
      User user = new User(rs.getLong("id"), rs.getString("firstname")); 
      user.email = rs.getString("email"); 
      System.out.println("recup du user "+user.id + user.firstname); 
      return user; 
     } 
    }; 

} 

Même avec java jeter l'exception, à la recherche dans la base de données montre que le rollback ne se produit jamais et le premier insert est conservée.

Pourquoi?

+0

Avez-vous 'org.springframework: spring-tx' dans vos dépendances? – Gregg

+0

Avez-vous consulté le guide de démarrage pour les transactions de printemps? https://spring.io/guides/gs/managing-transactions/ –

+0

Salut @Gregg, je pensais que 'org.springframework: spring-tx'it était inclus dans' compile ('org.springframework.boot: spring-boot- starter-jdbc ') 'J'ai essayé de l'ajouter ce matin et ça ne change rien – AeroEd

Répondre

1

solution trouvée: le moteur de stockage par défaut (MyISAM) qui a été installé lors de la création d'une table mysql ne peut pas gérer plusieurs transactions d'instructions. Créer des tables avec le moteur d'InnoDB fait que tout fonctionne parfaitement.