为什么不提交Requires_New的交易? [英] Why does not commit transaction of Requires_New?

查看:256
本文介绍了为什么不提交Requires_New的交易?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题。我正在使用java应用服务器(sap netweaver),我正在使用ejb 3.0



所以我想要一个一个地插入数据库。因为我有太多的数据,我必须分割数据。所以我做了测试代码,它的工作,但它没有工作,我想要。



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



示例代码在下面;

  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实现TestTransactionLocal {

@EJB
DatabaseServiceLocal databaseService;

@Resource
EJBContext上下文;

@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 commit);

Thread.sleep(5000); (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 commit);

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函数结束,则插入函数将全部提交。



为什么没有提交新的交易?



注意:如果我将onStart函数REQUIRED的transaction属性更改为NOT_SUPPORTED,它的工作原理就是我想要的。为什么它以这种方式工作?

解决方案

您必须使用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


I have a problem. I am working on java application server(sap netweaver) with I am using ejb 3.0

So I want to database insert one by one. Because I have too much data and i have to divide data. So I made try test code and it did work but it did not work as I want.

I want to create a new transaction for each part and of course at the end method(transaction) should be commit.

Sample code is below;

package com.transaction.jobs;

import javax.ejb.Local;

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

    public void onStart();

    public void insertObject(int i);
}

and

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();
        }
    }

}

The insertObject(Requires_New) function is work but it did not commit. It waiting for commit other onStart(REQUIRED) function. If mytimer function is end, the insert function makes all commit.

Why new transaction is did not committed?

Note: If I change transaction attribute of the onStart function REQUIRED to NOT_SUPPORTED it works as I want. Why it works this way?

解决方案

You have to initialize another TestTransactionLocal with a use of SessionContext#getBusinessObject method. This way your TestTransactionLocal instance will respect @TransactionAttribute annotation.

@Resource
private SessionContext sessionContext;

private TestTransactionLocal local;

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

Then invoke insertObject() through this new reference:

local.insertObject(i);

See this blog post: http://www.adam-bien.com/roller/abien/entry/how_to_self_invoke_ejb

这篇关于为什么不提交Requires_New的交易?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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