当前位置: 首页 > 知识库问答 >
问题:

EntityManager.persist()方法挂起

鱼锦
2023-03-14

不确定是否有人遇到过这个问题。我正在使用带有EJB3.1的JBoss7.1应用程序服务器和带有HiberNate实现的JPA2.0。我正在使用后端Oracle 11g数据库。请参阅下面的代码。我正在使用由HTTP GET请求驱动的servlet调用我的EJB。

当我在下面的代码中注释掉 context.setRollbackOnly() 时,我的网页会永远挂起,一段时间后我会得到下面的堆栈跟踪(如果我调试,它会让我直到 persist() 方法,然后不会去任何地方)。

21:56:22,765 WARN [com.arjuna.ats.arjuna](事务收割者)ARJUNA012117: TransactionReaper::检查TX 0超时:ffffc 0a 80005:57 a 36 CD 7:5303 d0bf:30处于状态运行21:56:22,767 WARN [com.arjuna.ats.arjuna](事务收割者工作器2) ARJUNA012095:中止操作id 0:ffffc 0021:56:22,768 WARN[com . Arjuna . ATS . Arjuna](Transaction Reaper Worker 2)Arjuna 012108:checked action::check-atomic action 0:ffffc 0a 80005:57 a 36 CD 7:5303 d0bf:30中止,1个线程处于活动状态!21:56:23,266 WARN[com . Arjuna . ATS . Arjuna](Transaction Reaper)Arjuna 012117:Transaction Reaper::检查TX 0超时:ffffc 0a 80005:57 a 36 CD 7:5303 d0bf:30处于取消状态21:56:23,767 WARN[com . Arjuna . ATS . Arjuna](Transaction Reaper)Arjuna 012117:Transaction Reaper::检查TX 0超时:

取消注释 context.setRollbackOnly() 后,页面将加载,但后端表中没有记录。相同的代码间歇性地工作。我无法弄清楚它何时工作的实际模式!!谁能投射出一些光芒?

我的EJB代码如下-

import javax.annotation.Resource;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;
import javax.ejb.Local;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;


@Stateless
@Local(DepartmentLocal.class)
@TransactionManagement(TransactionManagementType.CONTAINER)
@DeclareRoles({"Admin", "Guest"})
public class DepartmentBean{

@Resource
private SessionContext context;

@PersistenceContext(unitName="department-pu")
private EntityManager em;



@TransactionAttribute(TransactionAttributeType.REQUIRED)
@RolesAllowed({"Admin"})
public long addDepartment(Department dep){

    em.persist(dep);        

    //context.setRollbackOnly();
    return dep.getDepartmentId();
}

}

更新:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="DEPARTMENTS")
public class Department {
 @Id
 @Column(name="DEPARTMENT_ID")
 private long departmentId;

@Column(name="DEPARTMENT_NAME")
private String departmentName;

@Column(name="MANAGER_ID")
private long managerId;

@Column(name="LOCATION_ID")
private long locationId;

public long getDepartmentId() {
    return departmentId;
}

public void setDepartmentId(long departmentId) {
    this.departmentId = departmentId;
}

public String getDepartmentName() {
    return departmentName;
}

public void setDepartmentName(String departmentName) {
    this.departmentName = departmentName;
}

public long getManagerId() {
    return managerId;
}

public void setManagerId(long managerId) {
    this.managerId = managerId;
}

public long getLocationId() {
    return locationId;
}

public void setLocationId(long locationId) {
    this.locationId = locationId;
}


}

META-INF/persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="department-pu" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:jboss/datasources/OracleDS</jta-data-source>
    <class>Department</class>       
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
        <property name="show_sql" value="false"/>
    </properties>
</persistence-unit>

在standalone-full.xml

   <datasources>
       ...
       <datasource jta="true" jndi-name="java:jboss/datasources/OracleDS" pool-name="OjdbcPool" enabled="true" use-java-context="true">
                <connection-url>jdbc:oracle:thin:@localhost:1521:xe</connection-url>
                <driver>ojdbc</driver>
                <pool>
                    <min-pool-size>10</min-pool-size>
                    <max-pool-size>20</max-pool-size>
                    <prefill>true</prefill>
                </pool>
                <security>
                    <user-name>xxx</user-name>
                    <password>xxx</password>
                </security>
            </datasource>
            <drivers>
                <driver name="ojdbc" module="oracle.jdbc">
                    <xa-datasource-class>oracle.jdbc.OracleDriver</xa-datasource-class>
                </driver>
            </drivers>

   </datasources>

共有2个答案

巫马翰翮
2023-03-14

问题是这是一个XA数据源定义,一个非XA驱动程序被传递给它。

XA 数据源允许参与多资源事务,例如,可以执行跨两个数据库上的表的事务。

有关设置和 XA 数据源的 Oracle 示例,请参阅此处,您将需要 namelly oracle.jdbc.xa.client.OracleXADataSource

XA事务使用两阶段提交协议,所有参与者投票决定事务是否“可提交”,只有在第二步才真正提交(或回滚)。

在这里,JTA事务管理器似乎正在等待提交确认,但从未收到确认,因为使用的数据源不是XA数据源,所以它不知道两阶段提交协议。

作为一个解决方案,如果因为不需要多资源事务而不需要XA,那么就要把数据源变成非XA的——例如local-tx-datasource。

否则,数据源必须是 XA,请按照上面的链接了解有关配置 XA 数据源的更多详细信息。

连鸿
2023-03-14

在< code>persist()中,表/行上有一个锁(这是可配置的),由于某种原因,Tx不能回滚...直到超时。

< code >部门实体看起来如何?,与表格匹配正确吗?,以及生成的sql是如何被ORM < code > insert 的?

至少EJB代码看起来没问题,如果您确定实体正确地映射了表,您就可以用它的锁关注数据库/ORM了。

选项:有时我建议不要setRollback,而是抛出一个runtime Exc,容器会自动标记为回滚Tx(并尽快从方法中退出),这将使您的代码更具表现力。

 类似资料:
  • 问题内容: 我正在使用银行gui应用程序,目前正在使用它,我的jdialog的setvisible方法似乎存在问题。用户提取有效金额后,我弹出一个简单的对话框,显示“交易正在进行中”。在我的dobackground方法中,我不断轮询以检查是否已收到交易。我尝试使用swingworker,但我不明白为什么它不起作用。如果我删除setvisible调用,它可以正常工作,那么为什么setvisible导

  • 问题内容: 我已经定义了此路由,但是对它的任何请求都会卡在“待处理”中并永远运行。 当我记录代码时,我看到后面跟着,这意味着find方法中的代码永远不会执行 模型 关于这是为什么的任何想法? 问题答案: 在您致电之前,您的猫鼬查询只会简单地排队。 在启动代码中添加如下代码以进行连接: 在连接字符串中,用数据库名称替换。

  • 问题内容: 我正在尝试使用Java学习套接字,并且成功地将数据发送到了在我自己的计算机上运行的ServerSocket。当我尝试使用readline从此套接字读取消息(以便仅回显自己发送的消息)时,程序将挂起并且不会返回。 这是代码: TCPClient是我定义的类,因此在我的家庭作业中使用swing之前,我可以在更简单的界面上测试程序。这是代码: 我的服务器很简单。建立连接后,它将进入此循环并停

  • 问题内容: 我只是不明白为什么必须使用Runtime.addShutdownHook。如果要在jvm退出时进行一些清理,为什么不重载daemon类的finalize方法。使用shutdown钩子而不是finalize方法的好处是什么。 还有一个不赞成使用的函数runFinalizersOnExit。如果将其设置为false,我相信终结器将不会运行。这与java保证终结器始终在垃圾回收之前运行是矛盾

  • 我有接口 然后创建了一个类,并实现了 IDE没有显示任何错误,但当我编译时,会出现以下错误 null 并且编译时错误已经消失。