与tomcat,mysql和eclipselink的Spring事务问题

时间:2011-10-22 18:26:43

标签: mysql spring tomcat transactions eclipselink

在使用eclipselink,tomcat和mysql进行弹簧交易的谷歌搜索后,我有很多困惑。请考虑以下问题并就此主题指导我。

  1. 我可以使用eclipseLink,tomcat和mysql环境运行spring事务吗?如果是这样配置怎么样?我使用了以下配置,我总是得到锁定异常。
  2. 的persistence.xml:

    <persistence-unit name="xxxxService" transaction-type="RESOURCE_LOCAL">
      <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
      <class>...</class>
      <class>...</class>
      <class>...</class>
      <properties> .... </properties>
    </persistence-unit>
    

    弹簧-beans.xml文件:

    <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
    
        <bean class="org.springframework.orm.jpa.JpaTransactionManager"
            id="transactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory" />
            <property name="jpaDialect" ref="jpaDialect" />
        </bean>
        <bean id="jpaVendorAdapter"
            class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
            <property name="showSql" value="true" />
            <property name="generateDdl" value="true" />
        <property name="databasePlatform" value="org.eclipse.persistence.platform.database.MySQLPlatform" />
        </bean>
        <bean
            class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"
            id="entityManagerFactory">
            <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
            <property name="jpaDialect" ref="jpaDialect" />
            <property name="persistenceUnitName" value="xxxxService" />
        </bean>     
    
        <tx:annotation-driven transaction-manager="transactionManager" />
    
        <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
    

    JAVA课程:

      @Transactional
    public void saveSumthg(Sumthg sumthg) throws Exception{
        someDAO.saveSumthg(sumthg);
    }
    
       @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public List<Sumthg> findActiveSumthgs(String username) {
        List<Sumthg> sumthgs = someDAO.findActiveSumthgs(username);
        return sumthgs ;
    }
    

    我在这里做错了吗?我不确定Spring事务处理是否与tomcat一起正常工作,因为我没有使用JTA事务。

    1. 使用EclipseLInk和mysql,Id生成策略与Sequence表一起使用,并且在表中仅为所有事务更新一行。我怀疑这会导致锁定问题。我对么?如果是这样,我该如何避免这种情况?
    2. Domain类中的ID生成配置如下:

      @Id
      @Column(name = "some_id", unique = true, nullable = false)
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;
      

      在mysql架构中,创建了一个名为SEQUENCE的新表,并在其中存储了一个值。每次插入一行时,我都会从这里获取id。由于读取和更新了相同的值,我怀疑这会导致锁定问题。 如果我是对的,我怎么能避免这个问题?

      期待您的回答。

      感谢。

      得到了更新 - 我可以看到以下是日志:

      Internal Exception: java.sql.SQLException: Lock wait timeout exceeded; try restarting
      transaction
      Error Code: 1205
      Call: UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?
         bind => [50, SEQ_GEN]
      Query: DataModifyQuery(name="SEQUENCE" sql="UPDATE SEQUENCE SET SEQ_COUNT = 
      SEQ_COUNT   + ? WHERE SEQ_NAME = ?")]
      

      很明显,这种情况正在发生,因为SEQUENCE表中的相同值正被多个线程修改。我可以在这种情况下使用的最佳ID生成策略是什么?

2 个答案:

答案 0 :(得分:0)

问题是您使用的是最差的并发ID GENERATION解决方案(TABLE_SECUENCE)。 在这种情况下,最好的解决方案是使用SEQUENCE GENERATION。

序列发生器处理并发性要好得多。

答案 1 :(得分:0)

我无法看到你将如何获得锁定异常。你在运行多个线程/客户端吗?尝试设置最好的登录以查看正在发生的事情。

EclipseLink通常会在事务之外分配序列ID,因此通常不会发生任何锁定冲突。您还可以在EclipseLink中启用序列连接池,该池始终使用单独的连接来分配ID以避免任何锁定冲突。