【问题标题】:Why does not commit transaction of Requires_New?为什么不提交Requires_New的事务?
【发布时间】:2015-04-07 08:38:16
【问题描述】:

我正在使用 EJB 3.0 开发 SAP java 应用服务器

我想一一插入数据库。因为我有太多的数据,我必须划分数据。所以我尝试了测试代码,它确实有效,但没有按我的意愿工作。

我想为每个部分创建一个新事务,当然最后方法(事务)应该是提交。

示例代码如下;

package com.transaction.jobs;

import javax.ejb.Local;

/**
 *
 * @author muratdemir
 */
@Local
public interface TestTransactionLocal {

    public void onStart();

    public void insertObject(int i);
}

package com.transaction.jobs;

import com.transaction.service.DatabaseServiceLocal;
import com.transaction.entity.Item;
import com.transaction.entity.Logger;
import java.util.Date;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.EJBContext;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;

/**
 *
 * @author muratdemir
 */
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class TestTransactionService implements TestTransactionLocal {

    @EJB
    DatabaseServiceLocal databaseService;

    @Resource
    EJBContext context;

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void onStart() {
        try {
            System.out.println("START");

            Logger log1 = new Logger(new Date(), ">>>T1 commiting");
            databaseService.create(log1);

            System.out.println(">>>T1 committing");

            Thread.sleep(5000);

            for (int i = 1; i < 10; i++) {
                System.out.println("Call new Transaction");

                insertObject(i);

                Thread.sleep(2000);
            }

            Thread.sleep(5000);

            Logger log2 = new Logger(new Date(), "<<<T1 commiting");

            databaseService.create(log2);

            System.out.println("<<<T1 committing");

            Thread.sleep(5000);
            System.out.println("END");
        } catch (Exception e) {
            e.printStackTrace();
            context.setRollbackOnly();
        }

    }

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void insertObject(int i) {
        try {
            System.out.println("New Transaction Start i:" + i);

            Item item = new Item(new Date(), "Name_" + i);

            databaseService.create(item);

            System.out.println("commit transaction: " + i);
        } catch (Exception e) {
            e.printStackTrace();
            context.setRollbackOnly();
        }
    }

}

insertObject(Requires_New) 函数有效,但未提交。它等待提交其他 onStart(REQUIRED) 函数。如果 mytimer 函数结束,则 insert 函数将全部提交。

为什么没有提交新事务?

注意:如果我将 onStart 函数 REQUIRED 的事务属性更改为 NOT_SUPPORTED,它会按我的意愿工作。为什么会这样?

【问题讨论】:

    标签: java transactions ejb jta


    【解决方案1】:

    您必须使用 SessionContext#getBusinessObject 方法初始化另一个 TestTransactionLocal。这样,您的 TestTransactionLocal 实例将尊重 @TransactionAttribute 注释。

    @Resource
    private SessionContext sessionContext;
    
    private TestTransactionLocal local;
    
    @PostConstruct
    void init() {
        local = sessionContext.getBusinessObject(TestTransactionLocal.class);
    }
    

    然后通过这个新的引用调用 insertObject():

    local.insertObject(i);
    

    查看这篇博文:http://www.adam-bien.com/roller/abien/entry/how_to_self_invoke_ejb

    【讨论】:

      【解决方案2】:

      您直接调用prepare() 方法,因此不考虑事务注释。您需要通过它自己的接口调用它,即myTestTimerLocal.prepare(),以获得任何事务效果。

      【讨论】:

      • 我更新了问题。我试过@EJB TestTransactionLocal local; local.insertObject(i); 但没用。
      猜你喜欢
      • 2014-04-16
      • 2013-04-11
      • 1970-01-01
      • 1970-01-01
      • 2012-09-25
      • 2017-03-23
      • 1970-01-01
      • 2015-10-28
      • 2020-04-19
      相关资源
      最近更新 更多