簡體   English   中英

Spring只讀事務將數據提交給DB

[英]Spring read-only transaction committing data to the DB

我正在嘗試按照Spring Framework Reference的第11.5.2節實現服務方法的read-only事務,但事務仍然會自動將數據提交到數據庫。

我正在使用Spring 3.1.0.RELEASE,Hibernate 3.5.5-Final和Oracle 11g Express Edition Release 11.2.0.2.0。 這是我的設置:

建議,切入點,顧問和事務管理器的XML:

<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="get*" read-only="true" />
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="myServiceMethods" expression="execution(* my.example.service.*.*(..))" />
    <aop:advisor pointcut-ref="myServiceMethods" advice-ref="transactionAdvice" />
</aop:config>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
    <!-- the sessionFactory bean declaration does not set the -->
    <!-- hibernate.connection.autocommit property as either true or false -->
</bean>

服務界面:

package my.example.service;

public interface MyService {

    void getFoo();

    void bar();
}

服務實施:

package my.example.service.impl;

import my.example.dao.MyDao;
import my.example.domain.MyEntity;
import my.example.service.MyService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyServiceImpl implements MyService {

    @Autowired
    private MyDao dao;

    public void getFoo() {
        MyEntity example = this.dao.getMyEntity(1L);
        example.setSomeInteger(2);
        example.setSomeString("three");
    }

    public void bar() {
        MyEntity example = this.dao.getMyEntity(4L);
        example.setSomeInteger(5);
        example.setSomeString("six");
    }
}

在調用getFoo()bar() ,即使getFoo()被標記為read-only ,DB也會更新。 但如果我改變這兩行:

<tx:method name="get*" read-only="true" />
<tx:method name="*"/>

至:

<tx:method name="*" read-only="true" />

兩種方法都遵循read-only屬性,數據不會提交給DB。

這是怎么回事? 我究竟做錯了什么? 我錯過了什么?

我發現為什么read-only事務被覆蓋。 web.xml聲明了一個OpenSessionInViewFilter ,以前的開發人員在加載用戶及其在控制器/接口中的角色時用來阻止LazyInitializationException

這是過濾器聲明:

<filter>
    <filter-name>openSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>

我通過配置過濾器來解決這個問題,讓每個事務都使用自己的會話(稱為deferred mode )。

這是激活deferred mode的過濾器聲明:

<filter>
    <filter-name>openSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>singleSession</param-name>
        <param-value>false</param-value>
    </init-param>
</filter>

請閱讀過濾器的Javadoc中的NOTE。 我的DAO類擴展了org.springframework.orm.hibernate3.support.HibernateDaoSupport ,並且繼承方法返回的Hibernate Session getSession()getSessionFactory().getCurrentSession()將其flush模式設置為FlushMode.MANUAL ,而不是FlushMode.NEVER ,正如我在閱讀了這個SO答案后所說的那樣。

為什么不在@Transactional注釋上使用readOnly標志。

使用@Transactional(readOnly=true)注釋您的方法,並且Hibernate將嘗試以只讀方式執行事務,並且(我認為,您可能想要仔細檢查這一點)如果嘗試寫入將拋出異常。

在這方面,嘗試重新發明輪子毫無意義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM