简体   繁体   English

如何在WebSphere 8.0上获取TransactionManager?

[英]how can i obtain TransactionManager on WebSphere 8.0?

I tried to obtain the TransactionManager in a @Singleton SessionBean - EJB 3.1 - to control the scope of my transaction, because i have to access a database on a @PostConstruct method. 我试图在@Singleton SessionBean - EJB 3.1中获取TransactionManager来控制我的事务范围,因为我必须访问@PostConstruct方法的数据库。 If an exception occurrs, I cannot let the Container RollBack because it throws the TransactionRolledbackException: setRollbackOnly called from within a singleton post construct method. 如果发生异常,我不能让Container RollBack因为它抛出TransactionRolledbackException:从单例post构造方法中调用setRollbackOnly。

I am using a JTA DataSource and defined the @TransactionManagement(TransactionManagementType.BEAN) to override control of the transaction. 我正在使用JTA DataSource并定义了@TransactionManagement(TransactionManagementType.BEAN)来覆盖对事务的控制。

@Resource private TransactionManager transactionManager; @Resource私有TransactionManager transactionManager;

returns to me a NullPointerException when i try to do a "transactionManager.begin();". 当我尝试执行“transactionManager.begin();”时,返回给我一个NullPointerException。 Does anyone knows how to solve this ? 有谁知道如何解决这个问题?

UPDATE: 更新:

the code i am using is this: 我正在使用的代码是这样的:

    @Startup
    @Singleton
    @TransactionManagement(TransactionManagementType.BEAN)
    public class RuntimeContextEJB

{

    @EJB
    private RepositoryRecursosExternosFactoryEJB    repositoryRecursosExternosFactoryEJB;

    @EJB
    private MetodologiaIndiceLiquidezFactoryEJB     metodologiaIndiceLiquidezFactoryEJB;

    @EJB
    private FuncaoMatematicaFactoryEJB              funcaoMatematicaFactoryEJB;

    private boolean                                 bootstrapRunning    = false;

    private List<String>                            dadosMercadoMonitorados;

    @PersistenceContext(unitName = "crv-persistence-unit")
    private EntityManager                           entityManager;

    @Resource
    private TransactionManager transactionManager;


    @PostConstruct
    public void init()
    {
        // comentário
        MotorCalculoContext.setupMotorCalculoContext(repositoryRecursosExternosFactoryEJB, metodologiaIndiceLiquidezFactoryEJB,
                funcaoMatematicaFactoryEJB);
        carregaDadosMercadoMonitorados();

    }


    public void sinalizarInicioBootstrap()
    {
        bootstrapRunning = true;
    }


    public void sinalizarTerminoBootstrap()
    {
        bootstrapRunning = false;
    }


    public boolean isBootstrapRunnnig()
    {
        return bootstrapRunning;
    }

    public void carregaDadosMercadoMonitorados()
    {




        try
        {

            transactionManager.begin();

            this.dadosMercadoMonitorados = (List<String>) entityManager
                    .createQuery(
                            "SELECT DISTINCT(p.parametro.codigoDadoMercado) FROM PlanoExecucaoPasso p WHERE p.parametro.codigoDadoMercado <> '' AND p.parametro.codigoDadoMercado <> '0'")
                    .getResultList();
        }
        catch (Exception e)
        {
        }

    }

}

I think there should be a JNDI adress to add on the @Resource annotation, one that is specific for WebSphere, but i really can't find wich is. 我认为应该有一个JNDI地址添加@Resource注释,一个特定于WebSphere的注释,但我真的找不到它。

UPDATE: 更新:

why use JNDI on a container managed injection ? 为什么在容器管理注入上使用JNDI? Since i am getting a nullpointer exception from a direct injection, tried to use like the ex. 因为我从直接注入得到一个nullpointer异常,试图像ex一样使用。 on page 305 from OReilly Enterprise Java Beans 3.1 6th edition. 从OReilly Enterprise Java Beans 3.1第6版开始,第305页。

@Resource(mappedName = "java:/TransactionManager")
//mappedName is vendor-specific, and in this case points to an address in JNDI

tried this with no success. 尝试过这个没有成功。

UPDATE UPDATE

WebSphere is not getting our beans annotations - can't really know why - so the annotation: WebSphere没有得到我们的bean注释 - 不能真正知道原因 - 所以注释:

@TransactionManagement(TransactionManagementType.BEAN)

was not working. 没有用。 So, edited de ejb-jar.xml and added the following code: 因此,编辑了de ejb-jar.xml并添加了以下代码:

<transaction-type>Bean</transaction-type>

and the UserTransaction worked. 并且UserTransaction工作。 Thanks for the answers. 谢谢你的回答。

When you have bean managed transaction, you don't use javax.transaction.TransactionManager but instead you use javax.transaction.UserTransaction . 当您拥有bean托管事务时,不使用javax.transaction.TransactionManager ,而是使用javax.transaction.UserTransaction

And then you call begin, commit .... etc of UserTransaction interface. 然后你调用UserTransaction接口的begin,commit ....等。

Answer Updated: 答案已更新:

1) First of all, as I said, don't use TransactionManager . 1)首先,正如我所说,不要使用TransactionManager Use UserTransaction 使用UserTransaction

2) As you wanted to know the JNDI name of the UserTransaction object. 2)如您想知道UserTransaction对象的JNDI名称 It is java:comp/UserTransaction . 它是java:comp/UserTransaction But you need this only when your component is not managed. 但是,只有在不管理组件时才需要这样做。 ie: Servlet, EJB. 即: Servlet,EJB。 That process is called making a manual call to JNDI API 该过程称为手动调用JNDI API

3) Provide commit() or rollback() . 3)提供commit()rollback() None of them is present. 它们都不存在。

I am looking at your class and it seems alright. 我在看你的课,看起来还不错。

So, where is the problem ? 那么,问题出在哪里? (possibilities) (可能性)

1) Your class is not treated as EJB (container managed) and which is why injection fails. 1)您的类不被视为EJB(容器管理),这就是注入失败的原因。

2) Transaction service is not started before EJB @Startup or it fails to start. 2) EJB @Startup之前未启动事务服务或启动失败。

3) You have JTA Datasource configured in your persistence.xml . 3)您在persistence.xml中配置了JTA数据源 In which case, try: 在这种情况下,尝试:

@Resource
private EJBContext context;

userTransaction  = context.getUserTransaction(); 

Note: Please also provide full stack trace and persistence.xml in order to pinpoint exact problem. 注意:还请提供完整堆栈跟踪和persistence.xml以确定准确的问题。

You don't need to use the Transaction Manager in programmatic (BMT) session beans, unless you want to suspend() or resume() the associated transaction in some cases, use the UserTransaction instead . 您不需要在程序化(BMT)会话bean中使用事务管理器,除非您希望在某些情况下挂起()或resume()关联的事务,而是使用UserTransaction。

However, you can get a reference to the Transaction Manager in websphere by com.ibm.ws.Transaction.TransactionManagerFactory class using the static method getTransactionManager() . 但是,您可以使用静态方法getTransactionManager()通过com.ibm.ws.Transaction.TransactionManagerFactory类获取对websphere中的事务管理器的引用。

public TransactionManager getTransactionManager() {
    return TransactionManagerFactory.getTransactionManager();
}

Here's some sample code that runs properly using UserTransaction to have control over transactions. 下面是一些使用UserTransaction正确运行的示例代码,可以控制事务。

@Singleton
@Startup
@TransactionManagement(TransactionManagementType.BEAN) 
public class SampleUT {

Logger logger = Logger.getLogger(SampleUT.class.getName()); 

@Resource
private UserTransaction ut;

@PostConstruct
public void postConstruct()
{
    logger.info("PostConstruct called");

    try {
        ut.begin();
...

The NullPointerException you're getting is probably related to you trying to use the injected resource inside the Constructor of your EJB. 您获得的NullPointerException可能与您尝试在EJB的构造函数中使用注入的资源有关。 You should be aware that the injected reference is never available until the constructor of the EJB is finished, so if you try to use any injected reference inside the constructor, it will throw a NullPointerException. 您应该知道注入的引用在EJB的构造函数完成之前永远不可用,因此如果您尝试在构造函数中使用任何注入的引用,它将抛出NullPointerException。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM