EntityManager.persist()方法挂起 [英] EntityManager.persist() method hanging

查看:206
本文介绍了EntityManager.persist()方法挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Not sure if somebody faced this problem. I'm using Jboss7.1 Application server with EJB3.1 and JPA2.0 with Hibernate implementation. I'm using back-end Oracle 11g database. Please see the below code. I'm invoking my EJB using a servlet driven by a HTTP GET request.

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

When I comment out context.setRollbackOnly() in the below code, my web page just hangs forever and I get below stack trace after a while(if I debug, it takes me till persist() method and then doesn't go anywhere).


21:56:22,765 WARN [com.arjuna.ats.arjuna](交易收割者)ARJUNA012117:TransactionReaper :: TX的检查超时0:ffffc0a80005:57a36cd7:5303d0bf:30状态为RUN
21:56:22,767 WARN [com.arjuna.ats.arjuna](交易收割者工人2)ARJUNA012095:行动中止ID 0:ffffc0a80005:57a36cd7:5303d0bf :当多个线程在其中活动时调用30。
21:56:22,768 WARN [com.arjuna.ats.arjuna](交易收割者工人2)ARJUNA012108:CheckedAction :: check - 原子动作0:ffffc0a80005:57a36cd7:5303d0bf:30中止,1个线程处于活动状态!
21:56:23,266 WARN [com.arjuna.ats.arjuna](交易收割者)ARJUNA012117:TransactionReaper :: TX 0检查超时:ffffc0a80005:57a36cd7:5303d0bf:30状态CANCEL
21: 56:23,767 WARN [com.arjuna.ats.arjuna](交易收割者)ARJUNA012117:TransactionReaper :: TX 0检查超时:ffffc0a80005:57a36cd7:5303d0bf:30状态CANCEL_INTERRUPTED
21:56:23,768 WARN [com .arjuna.ats.arjuna](交易收割者)ARJUNA012120:TransactionReaper :: check worker线程[Transaction Reaper Worker 2,5,main]在取消TX 0时没有响应中断:ffffc0a80005:57a36cd7:5303d0bf:30 - worker标记为僵尸和TX预定标记为回滚
21:56:23,770 WARN [com.arjuna.ats.arjuna](交易收割者)ARJUNA012110:TransactionReaper ::检查成功标记为TX 0:ffffc0a80005:57a36cd7:5303d0bf: 30仅作为回滚

21:56:22,765 WARN [com.arjuna.ats.arjuna] (Transaction Reaper) ARJUNA012117: TransactionReaper::check timeout for TX 0:ffffc0a80005:57a36cd7:5303d0bf:30 in state RUN 21:56:22,767 WARN [com.arjuna.ats.arjuna] (Transaction Reaper Worker 2) ARJUNA012095: Abort of action id 0:ffffc0a80005:57a36cd7:5303d0bf:30 invoked while multiple threads active within it. 21:56:22,768 WARN [com.arjuna.ats.arjuna] (Transaction Reaper Worker 2) ARJUNA012108: CheckedAction::check - atomic action 0:ffffc0a80005:57a36cd7:5303d0bf:30 aborting with 1 threads active! 21:56:23,266 WARN [com.arjuna.ats.arjuna] (Transaction Reaper) ARJUNA012117: TransactionReaper::check timeout for TX 0:ffffc0a80005:57a36cd7:5303d0bf:30 in state CANCEL 21:56:23,767 WARN [com.arjuna.ats.arjuna] (Transaction Reaper) ARJUNA012117: TransactionReaper::check timeout for TX 0:ffffc0a80005:57a36cd7:5303d0bf:30 in state CANCEL_INTERRUPTED 21:56:23,768 WARN [com.arjuna.ats.arjuna] (Transaction Reaper) ARJUNA012120: TransactionReaper::check worker Thread[Transaction Reaper Worker 2,5,main] not responding to interrupt when cancelling TX 0:ffffc0a80005:57a36cd7:5303d0bf:30 -- worker marked as zombie and TX scheduled for mark-as-rollback 21:56:23,770 WARN [com.arjuna.ats.arjuna] (Transaction Reaper) ARJUNA012110: TransactionReaper::check successfuly marked TX 0:ffffc0a80005:57a36cd7:5303d0bf:30 as rollback only

使用 context.setRollbackOnly()取消注释,然后页面加载,但没有记录后端桌子。相同的代码间歇性地工作。我无法弄清楚它何时起作用的实际模式!任何人都可以投光吗?

With context.setRollbackOnly() uncommented, then page loads, but there is no record in the back-end table. The same code works intermittently. I can't figure out the actual pattern of when it works!! Can anyone throw some light?

我的EJB代码如下 -

My EJB code is below -

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

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中

In 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>


推荐答案

persist()对表/行有一个锁(好吧,这是可配置的),由于某种原因,Tx因为这个而无法回滚......直到超时到达。

At persist() there is a lock over the table/row (well, that is configurable), and for some reason the Tx can not be rollback because of that... until the timeout arrives.

如何查看部门实体?,正确匹配表?,以及生成的sql 如何插入由ORM?

How looks the Department entity?, match correctly to the table?, and how is the generated sql insert by the ORM?

至少EJB代码看起来没问题,如果你确定实体正确映射了表,你可以专注于数据库/ ORM及其锁定。

At least the EJB code looks ok and if you are sure that the entity correctly maps the table, you can focus at database/ORM with its locks.

选项:有时候我会建议抛出一个runtimeException( IllegalStateException)而不是setRollback IllegalArgumentException 或自定义),容器会自动标记回滚Tx(并尽快退出方法),这样会让你的代码更具表现力。

Option: Sometimes instead of setRollback, I would suggest to throw a runtimeException (IllegalStateException, IllegalArgumentException or a custom), the container will mark automatically for rollback the Tx (and exit as soon as possible from the method), this would make your code more expressive .

这篇关于EntityManager.persist()方法挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆