繁体   English   中英

与JPA,Hibernate和Spring并发

[英]Concurrency with JPA, Hibernate and Spring

我正在使用带有JPA注释的Hibernate 4.2.5和Spring 3.2.4。

我在服务中有以下方法

@Override
@Transactional
public Foo getFoo(String fooName) {
    Foo foo = fooDao.findByName(fooName);
    if (foo == null)
        return null;
    foo.setBar(new Date());
    return fooDao.save(foo);
}

fooDao只是一个自动interface FooDao extends JpaRepository<Foo, Long>

如果现在有多个线程访问getFoo方法,则会发生以下情况:

Thread 1: Foo foo1 = getFoo("name1");
Thread 2: Foo foo2 = getFoo("name2");

但是foo1.getName() == foo2.getName() == "name2" (或“ name1”)。 这可能是并发问题,线程在save和select last_update_id之间切换

我试图添加事务隔离,但这也无济于事。 我该如何预防呢? (显然, synchronized方法也无济于事)

编辑:我的applicationContext:

<?xml version="1.0" encoding="UTF-8"?>
<beans ...">
    <!-- ======== BoneCP ======== -->
    <bean id="mainDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
        <!-- ... -->
    </bean>
    <!-- ======== SPRING ======== -->
    <context:annotation-config />
    <context:component-scan base-package="foo.bar" />
    <jpa:repositories base-package="foo.bar" />
    <bean id="dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
        <property name="targetDataSource">
            <ref local="mainDataSource" />
        </property>
    </bean>
    <!-- ======== HIBERNATE / JPA ======== -->
    <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="generateDdl" value="false" />
        <property name="showSql" value="false" />
        <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
        <property name="database" value="MYSQL" />
    </bean>
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="de.cmr.cmair.server.db.model" />
        <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
        <property name="persistenceUnitName" value="persistenceUnit" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">validate</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.use_sql_comments">true</prop>
                <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
                <prop key="hibernate.current_session_context_class">jta</prop>
            </props>
        </property>
    </bean>
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager" />
    <!-- the transactional advice -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true" />
            <tx:method name="*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="allDaoMethods" expression="execution(* de.cmr.cmair.server.db.service.*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="allDaoMethods" />
    </aop:config>
</beans>

Foo类:

@Entity
@Table(name = "FOO")
public class Foo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", unique = true, nullable = false)
    private long id;
    @Column(name = "BAR")
    private Date bar;
    @Column(name = "NAME", length = 225)
    private String name;

    // ... setters / getters
}

我只是意识到我不使用版本控制/乐观锁定,但是我不确定这是否对这个问题有影响。

最好的解决方案是进行乐观锁定,或者在用户尝试编辑记录时应锁定记录。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM