2017-07-26 75 views
0

我有2個存儲庫 - 每個存儲庫都有針對不同對象的保存方法。 我想執行這兩個方法作爲事務,這意味着如果其中一個失敗,事務將被回滾。 (這在我看來是交易的意義)。如何在@Transactional中實現春季真正的交易

這裏是我的代碼:

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

我的構建:

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') 
} 

爲了測試它,我在我的控制器saveTomato改變一個數據庫列的名稱在番茄臺,所以(番茄)方法會失敗。如果發生這種情況,我想要保存的香蕉回滾。我認爲它應該像@Transactional方法註釋一樣工作,但我錯了。

那麼如何實現我的目標呢?

+0

你不使用彈簧引導,是嗎?如果沒有,你是否聲明瞭'DataSourceTransactionManager'?請顯示你的配置。 – alfcope

+0

請保持會話工廠和事務對象。 –

+0

您是使用'@ EnableAutoConfiguration'創建數據源嗎?你應該有一個由Spring自動創建的'DataSourceTransactionManager' bean。 – alfcope

回答

0

問題是我在MySQL表中使用了MyISAM,它們不支持事務。這對我來說是個大問題。我希望我的解決方案能夠幫助像我這樣的人。

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

爲bean:

import org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean; 

@Bean 
    public HibernateJpaSessionFactoryBean sessionFactory(){ 
     return new HibernateJpaSessionFactoryBean(); 
    } 

我不知道這是否是最好的解決辦法,但在我的情況下,工作的;)

+0

爲了獲得SessionFactory,我應該添加到spring引導中的依賴項? – ivanlirchev

+0

我認爲這種依賴關係:spring-boot-starter-data-jpa – Liline

+0

以及如何配置bean,因爲它表示沒有找到類型爲SessionFactory的bean?用@Transactional傳播還有什麼方法嗎?否則這個註釋是無用的。 – ivanlirchev

1

事務控制應該放在服務業務處理層

+0

不看結構。這只是一個例子。 – ivanlirchev