2016-10-19 9 views
0

Ich bin neu bei Springboot und ich überlege es für ein neues Projekt. Während ich seine Fähigkeiten teste, versage ich immer mit der @Transactional Annotation.SpringBoot @Transactional Rollback funktioniert nicht

ich eine kleine MySQL-Datenbank gemacht, auf die ich verbinden Setzen dieses application.properties Datei:

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 

Es folgt eine kleine Klasse, die ich auf die Datenbank zugreifen. In der insertUser (...) Methode habe ich absichtlich die INSERT-Anweisung wiederholt, sodass die zweite INSERT-Anweisung aufgrund eines doppelten Eintrags auf dem Primärschlüssel der Tabelle einen Rollback verursacht.

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; 
     } 
    }; 

} 

Selbst mit java der Ausnahme zu werfen, in der Datenbank suchen zeigt, dass die Rollbacks nie passiert und der erste Einsatz beibehalten wird.

Warum?

+0

Haben Sie 'org.springframework: spring-tx' in Ihren Abhängigkeiten? – Gregg

+0

Haben Sie den Leitfaden für den Beginn der Frühlingstransaktionen gelesen? https://spring.io/guides/gs/managing-transactions/ –

+0

Hallo @Gregg, ich dachte 'org.springframework: spring-tx'it wurde in' compile ('org.springframework.boot: spring-boot- starter-jdbc ') 'Ich habe versucht, es heute Morgen hinzuzufügen, und es ändert nichts – AeroEd

Antwort

1

Lösung gefunden: Die Standardspeicher-Engine (MyISAM), die beim Erstellen einer MySQL-Tabelle verwendet wurde, kann nicht mit mehreren Anweisungstransaktionen umgehen. Erstellen Tabellen mit InnoDB-Engine macht alles perfekt funktioniert.

Verwandte Themen