JBoss 4.x 上的 EJB 2.x 事务隔离
EJB 2.x transaction isolation on JBoss 4.x
我们有一个遗留应用程序,它是 运行 在 JBoss 3.x 实例上,无法更改或重写。由于以下问题可能会出现在多个位置,我将给出一个稍微抽象的示例,所以如果您需要更多信息,请不要犹豫,我会尽力收集。
主要问题如下:虽然应用程序在 JBoss 3.x 上运行良好,但我们希望将其迁移到 JBoss 4.x 以启用慢速过渡到 EJB 3.x 或 JPA 等技术。我知道 JBoss 4.x 早已超过其使用寿命,但不幸的是,没有办法解决这种情况(除了将 运行 保持在 3.x 上)。
在我们的测试中,我们遇到了这样一种情况,即同一事务中的查询可以读取未提交的数据,而未提交的关系则不能。
下面是系统外观的一些抽象代码:
实体(XML是通过xdoclet创建的,为了简单起见我省略了它。如果需要设置,我可以添加它们):
public abstract class Foo extends EntityBean, ...
{
...
public abstract RelationshipLocal getRelationship( );
public abstract void setRelationship( RelationshipLocal relationshipEntity );
public StammdatenAuthProcStepPK ejbCreate( RelationshipLocal relationshipEntity, ... )
throws javax.ejb.CreateException
{
setComment( "some comment" );
}
public void ejbPostCreate( RelationshipLocal relationshipEntity, ... )
throws javax.ejb.CreateException
{
setRelationship( relationshipEntity );
}
}
DAO 方法:
public Long getRelationshipUid( ... )
{
Connection conn = getDataSource().getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery( "SELECT relationshipUid FROM foo WHERE ...;" );
if( rs.next() )
{
long relationshipUid = rs.getLong( "relationshipUid" );
if( !rs.wasNull() ) //always false, i.e. relationshipUid is always null
{
return new Long (relationshipUid);
}
}
return null;
}
据我了解系统,我们有以下顺序:
- 开始交易
- 创建实体(调用
ejbCreate()
并发出 INSERT)
- 更新关系(调用
ejbPostCreate()
并发出更新)
- select关系uid来自使用上述DAO方法新建的实体
- 用那个 uid 做点什么(我不知道具体是什么)
- 提交交易
由于我们在 ejbCreate()
中设置了字段,因此事务隔离级别似乎设置为读取未提交,但是我不知道在 EJB 2.x 中的何处进行检查。
在 EJB 3.x 中,我会使用 EntityManager.refresh()
并且可能首先使用手册 flush()
,但是由于 EJB 2.x 没有 EntityManager ' 似乎是一个选择。
我们尝试更改 standardjboss.xml 中的容器设置,例如<commit-option>
但没有任何成功。
还有其他想法我们可以照顾什么或这里可能出什么问题吗?
欢迎任何全局选项(例如 JBoss 设置,无需更改代码,因为我们不知道所有地方)。
我们最近从 JBOSS 4 迁移到 EAP 6。但是在我们的 JBOSS 4 配置中,我们的容器配置 (standardjboss.xml) 中有以下设置:
<container-configuration>
<container-name>Standard CMP 2.x EntityBean post create</container-name>
<call-logging>false</call-logging>
<invoker-proxy-binding-name>entity-rmi-invoker</invoker-proxy-binding-name>
<sync-on-commit-only>false</sync-on-commit-only>
<insert-after-ejb-post-create>true</insert-after-ejb-post-create>
...
<container-configuration>
将设置 "insert-after-ejb-post-create" 更改为 true 将确保正确数据库交互,以便您的数据在同一事务中可供读取。
我们有一个遗留应用程序,它是 运行 在 JBoss 3.x 实例上,无法更改或重写。由于以下问题可能会出现在多个位置,我将给出一个稍微抽象的示例,所以如果您需要更多信息,请不要犹豫,我会尽力收集。
主要问题如下:虽然应用程序在 JBoss 3.x 上运行良好,但我们希望将其迁移到 JBoss 4.x 以启用慢速过渡到 EJB 3.x 或 JPA 等技术。我知道 JBoss 4.x 早已超过其使用寿命,但不幸的是,没有办法解决这种情况(除了将 运行 保持在 3.x 上)。
在我们的测试中,我们遇到了这样一种情况,即同一事务中的查询可以读取未提交的数据,而未提交的关系则不能。
下面是系统外观的一些抽象代码:
实体(XML是通过xdoclet创建的,为了简单起见我省略了它。如果需要设置,我可以添加它们):
public abstract class Foo extends EntityBean, ...
{
...
public abstract RelationshipLocal getRelationship( );
public abstract void setRelationship( RelationshipLocal relationshipEntity );
public StammdatenAuthProcStepPK ejbCreate( RelationshipLocal relationshipEntity, ... )
throws javax.ejb.CreateException
{
setComment( "some comment" );
}
public void ejbPostCreate( RelationshipLocal relationshipEntity, ... )
throws javax.ejb.CreateException
{
setRelationship( relationshipEntity );
}
}
DAO 方法:
public Long getRelationshipUid( ... )
{
Connection conn = getDataSource().getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery( "SELECT relationshipUid FROM foo WHERE ...;" );
if( rs.next() )
{
long relationshipUid = rs.getLong( "relationshipUid" );
if( !rs.wasNull() ) //always false, i.e. relationshipUid is always null
{
return new Long (relationshipUid);
}
}
return null;
}
据我了解系统,我们有以下顺序:
- 开始交易
- 创建实体(调用
ejbCreate()
并发出 INSERT) - 更新关系(调用
ejbPostCreate()
并发出更新) - select关系uid来自使用上述DAO方法新建的实体
- 用那个 uid 做点什么(我不知道具体是什么)
- 提交交易
由于我们在 ejbCreate()
中设置了字段,因此事务隔离级别似乎设置为读取未提交,但是我不知道在 EJB 2.x 中的何处进行检查。
在 EJB 3.x 中,我会使用 EntityManager.refresh()
并且可能首先使用手册 flush()
,但是由于 EJB 2.x 没有 EntityManager ' 似乎是一个选择。
我们尝试更改 standardjboss.xml 中的容器设置,例如<commit-option>
但没有任何成功。
还有其他想法我们可以照顾什么或这里可能出什么问题吗?
欢迎任何全局选项(例如 JBoss 设置,无需更改代码,因为我们不知道所有地方)。
我们最近从 JBOSS 4 迁移到 EAP 6。但是在我们的 JBOSS 4 配置中,我们的容器配置 (standardjboss.xml) 中有以下设置:
<container-configuration>
<container-name>Standard CMP 2.x EntityBean post create</container-name>
<call-logging>false</call-logging>
<invoker-proxy-binding-name>entity-rmi-invoker</invoker-proxy-binding-name>
<sync-on-commit-only>false</sync-on-commit-only>
<insert-after-ejb-post-create>true</insert-after-ejb-post-create>
...
<container-configuration>
将设置 "insert-after-ejb-post-create" 更改为 true 将确保正确数据库交互,以便您的数据在同一事务中可供读取。