Reputation: 27
I have 2 repositories - every repository have save methods for different object. I want to execute these two methods as transaction, which means if one of them fail, the transaction will be rolled back. (this is the meaning of transaction in my opinion).
Here is my code:
@Repository
public class BananaRep {
private JdbcTemplate jdbc;
@Autowired
public BananaRep(JdbcTemplate jdbc) {
this.jdbc = jdbc;
}
public void saveBanana(Banana banana) {
jdbc.update("insert into ......", ...);
}
}
@Repository
public class TomatoRep {
private JdbcTemplate jdbc;
@Autowired
public TomatoRep(JdbcTemplate jdbc) {
this.jdbc = jdbc;
}
public void saveTomato(Tomato tomato) {
jdbc.update("insert into ... ", ....);
}
}
@RestController
public class MixController {
@Autowired
BananaRep bananaRep;
@Autowired
TomatoRep tomatoRep;
@Transactional
@RequestMapping(value="/mix", method= RequestMethod.GET)
public Car mix() {
Banana banana = new Banana(....);
bananaRep.saveBanana(banana );
Tomato tomato= new Tomato(...);
tomatoRep.saveTomato(tomato);
return banana;
}
}
my build:
buildscript {
ext {
springBootVersion = '2.0.0.M2'
}
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-jersey')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-jdbc')
compile('mysql:mysql-connector-java')
}
In order to test it I change the name of one db column in the Tomato table, so in my controller saveTomato(tomato) method will fail. I want if this happen saved banana to be rolled back. I thought it should work like this with @Transactional method annotation but I am wrong.
How to achieve my goal then?
Upvotes: 0
Views: 557
Reputation: 27
The problem was that I used MyISAM in MySQL table and they do not support transactions. That was big problem for me. I hope my solution help other people like me.
Upvotes: 0
Reputation: 29
@Autowired
private SessionFactory sessionFactory;
@Transactional
@RequestMapping(value="/mix", method= RequestMethod.GET)
public Car mix() {
Session session = sessionFactory.openSession();
session.beginTransaction();
Banana banana = new Banana(....);
bananaRep.saveBanana(banana );
Tomato tomato= new Tomato(...);
tomatoRep.saveTomato(tomato);
session.getTransaction().commit();
return banana;
}
For the bean :
import org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean;
@Bean
public HibernateJpaSessionFactoryBean sessionFactory(){
return new HibernateJpaSessionFactoryBean();
}
I don't know if it's the best solution but in my case, that works ;)
Upvotes: 1
Reputation: 111
Transaction control should be placed in the service business processing layer
Upvotes: 1