2015-10-16 80 views
1

我有三个表server_detail,server_group,server_group_mappping和实体类如下。 (没有给出完整的代码细节)ejb3中两个会话bean之间的事务

@Entity 
@Table(name = "server_detail") 
public class ServerBean implements Serializable { 
private static final long serialVersionUID = 1L; 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = "server_id") 
private Integer ServerId; 

@Column(name = "name") 
private String serverName; 
.... 
} 

@Entity 
@Table(name = "server_group") 
public class ServerGroupBean implements Serializable { 
private static final long serialVersionUID = 1L; 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = "group_id") 
private Integer groupId; 

@Column(name = "name") 
private String groupName; 
.... 
} 

@Entity 
@IdClass(GroupMapPK.class) 
@Table(name = "server_group_mapping") 
public class ServerGroupMapBean implements Serializable { 
private static final long serialVersionUID = 1L; 
@Id 
@Column(name = "group_id") 
private Integer groupId; 
@Id 
@Column(name = "server_id") 
private Integer serverId; 
.... 
} 

有一个包装类,来管理实体bean的操作如下

@Stateless 
@Local 
public class ServerClient implements ServerLocal { 
@PersistenceContext 
private EntityManager em; 

public ServerClient() { 
} 
public ServerBean create(java.lang.String name) { 
    ServerBean bean = new ServerBean(name); 
    em.persist(bean); 
    return bean; 
} 
public ServerBean update(ServerBean bean){ 
    return (em.contains(bean) ? bean : em.merge(bean)); 
} 
public void remove(ServerBean bean) { 
    em.remove(em.contains(bean) ? bean : em.merge(bean)); 
} 


@Stateless 
@Local 
public class ServerGroupClient implements ServerGroupLocal { 
@PersistenceContext 
private EntityManager em; 

public ServerGroupClient() { 
} 
public ServerGroupBean create(java.lang.Integer name) { 
    ServerGroupBean bean = new ServerGroupBean(name); 
    em.persist(bean); 
    return bean; 
} 
public ServerGroupBean update(ServerGroupBean bean){ 
    return (em.contains(bean) ? bean : em.merge(bean)); 
} 
public void remove(ServerGroupBean bean) { 
    em.remove(em.contains(bean) ? bean : em.merge(bean)); 
} 


@Stateless 
@Local 
public class ServerGroupMapClient implements ServerGroupMapLocal { 
@PersistenceContext 
private EntityManager em; 

public ServerGroupMapClient() { 
} 
public ServerGroupMapBean create(java.lang.Integer serverId,java.lang.Integer groupId) { 
    ServerGroupMapBean bean = new ServerBean(serverId, groupId); 
    em.persist(bean); 
    return bean; 
} 
public ServerBean update(ServerBean bean){ 
    return (em.contains(bean) ? bean : em.merge(bean)); 
} 
public void remove(ServerBean bean) { 
    em.remove(em.contains(bean) ? bean : em.merge(bean)); 
} 

我使用MYSQL(InnoDB引擎)为每个实体Bean类表格和它们的关系映射都是表格。

现在,我有GroupManager会话Bean类,它维护server_group和server_group_mapping表事务。当我创建服务器组和成员时,我必须执行以下事务。

1. First, add group id and group name to server_group table 
2. Second, map groupid with server id in server_group_mapping table 

以下是代码。

@Stateless 
@Local 
public class GroupManagerBean implements GroupManagerLocal { 
    @Resource 
    private SessionContext context; 

    private static GroupLocal GroupLocal; 
    private static GroupMapLocal GroupMapLocal; 
    public GroupManagerBean() { 
     GroupLocal = ServiceLocator.getGroupLocal(); 
     smscMapLocal = ServiceLocator.getGroupMapLocal(); 
    } 
    public void addGroup(GroupBean bean, Integer serverId){ 
     group = GroupLocal.create(bean.getGroupName()); ---> 1 
     ... 
     GroupMapLocal.create(group.getGroupId(), serverId); ----> 2 
     } 

ServiceLocator类是我可以查找我所有的bean的位置。 默认情况下,在ejb3事务属性是必需的。如果我执行addGroup()方法。得到以下例外。

javax.ejb.EJBTransactionRolledbackException: EntityManager must be access within a transaction 
at org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:115) 
at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:130) 
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:194) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:186) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:67) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67) 
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) 
at org.jboss.ejb3.session.SessionSpecContainer.invoke(SessionSpecContainer.java:219) 
at org.jboss.ejb3.proxy.handler.ProxyInvocationHandlerBase.invoke(ProxyInvocationHandlerBase.java:261) 
.... 
Caused by: javax.persistence.TransactionRequiredException: EntityManager must be access within a transaction 
at org.jboss.jpa.deployment.ManagedEntityManagerFactory.verifyInTx(ManagedEntityManagerFactory.java:155) 
at org.jboss.jpa.tx.TransactionScopedEntityManager.persist(TransactionScopedEntityManager.java:186) 
at com.example.GroupClient.create(GroupClient.java:37) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 

根据错误持久性管理器(GroupClient和GroupMapClient)超出我们的事务范围。我想知道,如何在将持久性管理器注入事务范围时使事务完全发生?

回答