tomcat、mysql和eclipse的Spring事务问题link
在用 eclipselink、tomcat 和 mysql 谷歌搜索 spring 事务后,我遇到了很多困惑。请考虑以下问题并就该主题指导我。
- 我可以在 eclipseLink、tomcat 和 mysql 环境中运行 spring 事务吗?如果是的话配置如何?我使用了以下配置,并且总是遇到锁定异常。
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>
Spring-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 事务。
- 使用 EclipseLInk 和 mysql,Id 生成策略与 Sequence 表一起使用,表中所有事务仅更新一行。我怀疑这会导致锁定问题。我说得对吗?如果是这样,我该如何避免这种情况?
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 生成策略是什么?
I've got lot of confusions after googling for spring transactions with eclipselink, tomcat and mysql. Please consider the following questions and guide me on this topic.
- Can i run spring transactions with eclipseLink, tomcat and mysql enviornment? if so how is the config? i have used the following config and i get lock exceptions always.
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>
Spring-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 class:
@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 ;
}
Am i doing anything wrong here? I'm not sure whether spring transaction handling works correctly with tomcat since i'm not using JTA transactions.
- With EclipseLInk and mysql, Id generation strategy goes with Sequence table and in the table only one row is updated for all transactions. I suspect that this causes lock issues. Am i correct? If so, how can i avoid this?
ID generation config in a Domain class is like this:
@Id
@Column(name = "some_id", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
In mysql schema, a new table named SEQUENCE is created and a value is stored in it. Each time when a row is inserted, the id is taken from here i think. Since the same value is read and updated, i suspect that this can cause locking issues.
If i'm correct, how can i avoid this issue??
Looking forward for your answers.
Thanks.
got an update - i can see the following is logs:
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 = ?")]
So it is clear that this is happening because the same value in SEQUENCE table is being modified by several threads. What is the best ID generation strategy i can use in this context??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题是您正在使用最差的并发 ID GENERATION 解决方案 (TABLE_SECUENCE)。
在这种情况下,最好的解决方案是使用序列生成。
排序器可以更好地处理并发性。
The problem is that you are using the worst concurrent ID GENERATION solution (TABLE_SECUENCE).
In this case the best solution is to use the SEQUENCE GENERATION.
The sequencers handle much better the concurrency.
我不明白你怎么总是会遇到锁异常。您正在运行多个线程/客户端吗?尝试将日志设置为最好,看看发生了什么。
EclipseLink 通常会在事务之外分配序列 ID,因此通常不会有任何锁定冲突。您还可以在 EclipseLink 中启用序列连接池,该池将始终使用单独的连接来分配 id,以避免任何锁定冲突。
I can't see how you would get lock exceptions always. Are you running multiple threads/clients? Try setting logging on finest to see what is going on.
EclipseLink will normally allocate sequence ids outside of the transaction, so would normally not have any locking conflicts. You can also enable a sequence connection pool in EclipseLink that will always use a seperate connection for allocating ids to avoid any locking conflicts.