如何确保Spring Transaction保持数据的完整性和一致性?

时间:2015-09-29 01:29:48

标签: spring hibernate spring-mvc spring-transactions

我的事务配置如下,我想知道当前配置是否会在接收并发请求时保持数据的完整性和一致性。如果代码没问题,那么并发请求会影响数据的完整性或一致性吗?

控制器

@RequestMapping(value = "/process", method = RequestMethod.POST)
    public String processNameForm(@ModelAttribute("Form") Form form, Model model)
            throws Exception {
        System.err.println("Received form details:" + form);
        long id = this.formService.saveForm(form);
        model.addAttribute("id", id);

        return "result";
    }

服务

@Transactional
public long saveForm(Form form) throws CannotSaveFormException {
    System.err.println("in saveForm of service");
    return formRepository.saveForm(form);
}

存储库

@Autowired
SessionFactory sessionFactory;

public long saveForm(Form form) {
    return (Long) sessionFactory.getCurrentSession().save(form);

配置

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:8889/Test" />
    <property name="username" value="jack" />
    <property name="password" value="jack" />
</bean>
<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
    depends-on="dataSource">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.test.model" />

    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">
                org.hibernate.dialect.MySQLDialect
            </prop>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.use_sql_comments">true</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">validate</prop>
        </props>
    </property>
</bean>


<bean
    class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

<bean id="transactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />

1 个答案:

答案 0 :(得分:1)

除非您的数据库表使用非事务性引擎,例如MyISAM,否则我认为您做得很好。并发请求不会影响您案例的完整性或一致性。

并发请求在基于Servlet的应用程序中非常常见。因此,为了打破完整性,一致性等,您需要不遗余力。您可以将事务隔离级别更改为@Transactional注释(或全局配置)中的READ_UNCOMMITTED,这将允许事务从另一个事务中读取未提交的数据。

另一种方法是将@Transactional中的传播属性设置为NEVER,甚至是SUPPORTS,而不存在预先存在的事务。

这两种情况看起来都不太可能。

另一种方法是让您的事务相关代码以某种方式依赖于可变的全局/共享状态。对于前者服务,DAO或控制器中的全局可变实例,可以通过多个请求进行设置。同样,我也不会在您的代码中看到这种情况。共享可变状态是大多数并发问题背后的原因。但据我所知,标准的Spring实践是完全避免它。事情可能是可变的或共享的,但不是两者都可以。对于前者在方法中改变你的实例的代码是安全的,因为它存在于堆栈上而不是并发问题,并且不会在线程之间共享。

除此之外,我认为你很安全。