【问题标题】:How to make sure integrity and consistency of data is maintained by Spring Transaction?如何确保 Spring Transaction 维护数据的完整性和一致性?
【发布时间】:2015-12-26 08:39:09
【问题描述】:

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

控制器

@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" />

【问题讨论】:

    标签: spring hibernate spring-mvc spring-transactions


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 在哪些情况下并发请求会影响数据的完整性或一致性?
    • @Jack 我刚刚更新了答案。 TL;博士;版本是:您需要竭尽全力破坏完整性、一致性等。
    • 感谢您的解释,您能给我一个共享和/或可变数据的示例吗?
    • @Jack 谈论共享可变状态,相关的并发问题可能是一个完整的答案。我能想到的任何简单的例子都太天真了,可能无助于理解相关的并发问题。但是链接here 可以作为一个很好的起点。另外,如果您愿意,可以尝试使用 best concurrency book,尤其是涉及到 java 时(但不同语言的概念保持不变)。
    猜你喜欢
    • 2016-04-13
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 2021-09-21
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    • 2020-08-04
    相关资源
    最近更新 更多