EJB回滚不适用于容器管理事务或Bean管理事务处理提交异常 [英] EJB Rollback does not work with Container Management Transaction or Bean Managament Transaction on commit exception

查看:368
本文介绍了EJB回滚不适用于容器管理事务或Bean管理事务处理提交异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了几个小时,试图用EJB来回滚。我有一个CDI控制器,我想删除一些对象。当我尝试在EJB中删除时,我得到一个异常,我尝试做回滚,但它不工作。在执行之前已经执行的每个SQL获取异常都不会回滚。 Obviusly这不是因为当我尝试在BMT中回滚时,我还有另一个例外。否则,当我尝试使用CMT我得到一个例外的hibernate,但我得到相同的结果,BMT。



我的控制器是

  @Named 
@Stateful
@ConversationScoped
public class PRequerimientoConjuntoCertificacionesBean implements Serializable {

/ **
*
* /
private static final long serialVersionUID = 1779474550283190942L;

@Inject
私人对话会话;

@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager entityManager;

@Inject
private DatosSesion datosSesion;

public void eliminationinarDocumento(){
// TODO hay que probarlo
DocumentoGeneradoSSCC documentoEliminar;
try {
documentoEliminar =(DocumentoGeneradoSSCC)daoBase
.getEntityById(DocumentoGeneradoSSCC.class,
10);文件系统
} catch(Exception e){
// TODO自动生成的catch块
e.printStackTrace();
}
}
}

使用EJB BMT如下:

  @Stateful 
@TransactionManagement(TransactionManagementType.BEAN)
public class DocumentoSSCCDAOBean实现IDocumentoSSCCDAOBeanLocal {

@Resource
private UserTransaction userTran;
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager entityManager;

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void removeDocumentoSSCC(
DocumentoGeneradoSSCC documentoGeneradoSSCC,
EntityManager entityManager){
// TODO色调probarlo
尝试{
userTran.begin();
// Eliminamos recurso asignado

entityManager
.remove(entityManager.contains(documentoGeneradoSSCC)?documentoGeneradoSSCC
:entityManager.merge(documentoGeneradoSSCC));
userTran.commit();
} catch(Exception e){
try {
userTran.rollback();
} catch(IllegalStateException e1){
// TODO自动生成的catch块
e1.printStackTrace();
} catch(SecurityException e1){
// TODO自动生成的catch块
e1.printStackTrace();
} catch(SystemException e1){
// TODO自动生成的catch块
e1.printStackTrace();
}
}
}
}

我得到这个堆栈跟踪


javax.transaction.RollbackException:ARJUNA016053:无法提交事务。




当我尝试回滚我得到这个


java.lang.IllegalStateException: BaseTransaction.rollback - ARJUNA016074:没有事务!


我有独立的数据源与JTA = true,

 < datasource jta =truejndi-name =java:jboss / datasources / ExampleDSpool-name =ExampleDSenabled =true java的上下文= 真 > 
< connection-url> jdbc:h2:mem:test; DB_CLOSE_DELAY = -1; DB_CLOSE_ON_EXIT = FALSE< / connection-url>
< driver> h2< / driver>
< security>
< user-name> sa< / user-name>
< password> sa< / password>
< / security>
< / datasource>

我的persistence.xml是

 < persistence-unit name =JusticiaGratuita
transaction-type =JTA>
<! - < description> Forge Persistence Unit< / description> - >
< provider> org.hibernate.ejb.HibernatePersistence< / provider>
< jta-data-source> java:jboss / datasources / ExampleDS< / jta-data-source>
< exclude-unlisted-classes> false< / exclude-unlisted-classes>

< properties>
< property name =hibernate.connection.driver_classvalue =$ {db.driver}/>
< property name =hibernate.connection.urlvalue =$ {db.url}/>
< property name =hibernate.connection.usernamevalue =$ {db.user}/>
< property name =hibernate.connection.passwordvalue =$ {db.pass}/>
< property name =hibernate.default_schemavalue =$ {db.schema}/>

< property name =hibernate.dialectvalue =org.hibernate.dialect.Oracle10gDialect/>
< property name =hibernate.hbm2ddl.autovalue =validate/>

< property name =hibernate.query.substitutionsvalue =true 1,false 0,'SI'1,'NO'0/>

< property name =hibernate.cache.provider_classvalue =org.hibernate.cache.EhCacheProvider/>
< property name =hibernate.jdbc.batch_sizevalue =20/>
< property name =hibernate.cache.use_second_level_cache
value =true/>
< property name =hibernate.cache.use_query_cachevalue =false/>

< property name =hibernate.show_sqlvalue =$ {db.showSql}/>
< property name =hibernate.format_sqlvalue =true/>

< property name =hibernate.connection.provider_class
value =org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider/>

< property name =hibernate.c3p0.max_sizevalue =30/>
< property name =hibernate.c3p0.min_sizevalue =5/>
< property name =hibernate.c3p0.acquire_incrementvalue =1/>
< property name =hibernate.c3p0.idle_test_periodvalue =3000/>
< property name =hibernate.c3p0.max_statementsvalue =0/>
< property name =hibernate.c3p0.timeoutvalue =0/>
< property name =hibernate.c3p0.autocommitvalue =false/>
< / properties>

< / persistence-unit>



您可以看到完整的stacktrace我的错误在这里: http://pastebin.com/h17JD2xP



我希望有任何帮助可以回滚并解决我的问题。



注意

解决方案

最后我解决了我的问题。我得到这个异常,因为在执行回滚之前,我执行提交,因此它是不可执行的,在执行后执行回滚,因为它们都是互斥的。因为我没有交易,因为提交关闭它,当回滚执行时没有事务。


java.lang.IllegalStateException:BaseTransaction最后我决定用CMT这样做。




  @TransactionManagement(TransactionManagementType.CONTAINER)
@Stateless
public class DocumentoSSCCServiceBean实现IDocumentoSSCCServiceBeanLocal {

@EJB
私人IDaoBase daoBase;

@PersistenceContext(unitName =JusticiaGratuita,type = PersistenceContextType.TRANSACTION)
private EntityManager entityManager;

@Resource
private EJBContext ejbContext;

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void removeDocumentoSSCC(long documentoGeneradoSSCC)
throws RollbackSajgException {
try {
/ / Buscamos el documento a Eliminar
DocumentoGeneradoSSCC docu =(DocumentoGeneradoSSCC)daoBase
.getEntityById(DocumentoGeneradoSSCC.class,
documentoGeneradoSSCC);

entityManager.remove(docu);
} catch(Exception e){

ejbContext.setRollbackOnly();
throw new RollbackSajgException();

}
}
}

我希望这可以帮助别人。


I spent hours triying to do a rollback with EJB. I have a CDI controller where I want to remove some object. When I try to remove in EJB I get an exception and I Try to do rollback, but It does not work. Every SQL which has been execute with commit before get the exception does not rollback. Obviusly It is not because I get another exception when I try to do the rollback in BMT. Otherwise when I tried with CMT I get an exception of hibernate but I get the same results that BMT.

My controller is

@Named
@Stateful
@ConversationScoped
public class PRequerimientoConjuntoCertificacionesBean implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1779474550283190942L;

    @Inject
    private Conversation conversation;

    @PersistenceContext(type = PersistenceContextType.TRANSACTION)
    private EntityManager entityManager;

    @Inject
    private DatosSesion datosSesion;

    public void eliminarDocumento() {
        // TODO hay que probarlo
        DocumentoGeneradoSSCC documentoEliminar;
        try {
            documentoEliminar = (DocumentoGeneradoSSCC) daoBase
                    .getEntityById(DocumentoGeneradoSSCC.class,
                            10);
            documentoSSCCDAOBean.removeDocumentoSSCC(documentoEliminar,entityManager);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

With EJB BMT as follows:

@Stateful
@TransactionManagement(TransactionManagementType.BEAN)
public class DocumentoSSCCDAOBean implements IDocumentoSSCCDAOBeanLocal {

    @Resource
    private UserTransaction userTran;
    @PersistenceContext(type = PersistenceContextType.TRANSACTION)
    private EntityManager entityManager;

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void removeDocumentoSSCC(
            DocumentoGeneradoSSCC documentoGeneradoSSCC,
            EntityManager entityManager) {
        // TODO hue probarlo
        try {
            userTran.begin();
            // Eliminamos recurso asignado

            entityManager
                    .remove(entityManager.contains(documentoGeneradoSSCC) ? documentoGeneradoSSCC
                            : entityManager.merge(documentoGeneradoSSCC));
            userTran.commit();
        } catch (Exception e) {
            try {
                userTran.rollback();
            } catch (IllegalStateException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (SecurityException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (SystemException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        } 
    }
}

and I get this stacktrace

javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.

and when I try to do rollback I get this

java.lang.IllegalStateException: BaseTransaction.rollback - ARJUNA016074: no transaction!

I have standlone datasource with JTA=true,

<datasource jta="true" jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
    <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
    <driver>h2</driver>
    <security>
        <user-name>sa</user-name>
        <password>sa</password>
    </security>
</datasource>

my persistence.xml is

<persistence-unit name="JusticiaGratuita"
    transaction-type="JTA">
    <!-- <description>Forge Persistence Unit</description> -->
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>

    <properties>
        <property name="hibernate.connection.driver_class" value="${db.driver}" />
        <property name="hibernate.connection.url" value="${db.url}" />
        <property name="hibernate.connection.username" value="${db.user}" />
        <property name="hibernate.connection.password" value="${db.pass}" />
        <property name="hibernate.default_schema" value="${db.schema}" />

        <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
        <property name="hibernate.hbm2ddl.auto" value="validate" />

        <property name="hibernate.query.substitutions" value="true 1, false 0,'SI' 1, 'NO' 0" />

        <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
        <property name="hibernate.jdbc.batch_size" value="20" />
        <property name="hibernate.cache.use_second_level_cache"
            value="true" />
        <property name="hibernate.cache.use_query_cache" value="false" />

        <property name="hibernate.show_sql" value="${db.showSql}" />
        <property name="hibernate.format_sql" value="true" />

        <property name="hibernate.connection.provider_class"
            value="org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider" />

        <property name="hibernate.c3p0.max_size" value="30" />
        <property name="hibernate.c3p0.min_size" value="5" />
        <property name="hibernate.c3p0.acquire_increment" value="1" />
        <property name="hibernate.c3p0.idle_test_period" value="3000" />
        <property name="hibernate.c3p0.max_statements" value="0" />
        <property name="hibernate.c3p0.timeout" value="0" />
        <property name="hibernate.c3p0.autocommit" value="false" />
    </properties>

</persistence-unit>

You can see full stacktrace of my error here: http://pastebin.com/h17JD2xP

I would appreciate any help to do rollback and solve my problems.

Regards

解决方案

Finally I solve my problem. I was getting this exception because before of doing the rollback I execute commit, therefore It is imposible execute rollback after commit as those both are exclusive each other. Cause of that I got no transaction, because commit close it and when rollback execute there was no transaction.

java.lang.IllegalStateException: BaseTransaction.rollback - ARJUNA016074: no transaction!

Finally I decided to do in this way with CMT.

@TransactionManagement(TransactionManagementType.CONTAINER)
@Stateless
public class DocumentoSSCCServiceBean implements IDocumentoSSCCServiceBeanLocal {

    @EJB
    private IDaoBase daoBase;

    @PersistenceContext(unitName = "JusticiaGratuita", type = PersistenceContextType.TRANSACTION)
    private EntityManager entityManager;

    @Resource
    private EJBContext ejbContext;

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void removeDocumentoSSCC(Long documentoGeneradoSSCC)
            throws RollbackSajgException {
        try {
            // Buscamos el documento a eliminar
            DocumentoGeneradoSSCC docu = (DocumentoGeneradoSSCC) daoBase
                    .getEntityById(DocumentoGeneradoSSCC.class,
                            documentoGeneradoSSCC);

            entityManager.remove(docu);
        } catch (Exception e) {

            ejbContext.setRollbackOnly();
            throw new RollbackSajgException();

        }
    }
}

I hope this could help someome.

这篇关于EJB回滚不适用于容器管理事务或Bean管理事务处理提交异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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