CDI交易管理:@Transactional如何工作? [英] CDI Transaction Management: How does @Transactional work?

查看:363
本文介绍了CDI交易管理:@Transactional如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  @Named(myBean)$ b在会话范围内拥有简单的CDI bean $ b @SessionScoped 
public class MyBean实现Serializable {
private static final long serialVersionUID = 1L;

@Inject
EntityManager em;
...

@Transactional
private void testInsert(){
long t = System.currentTimeMillis(); (int i = 1; i <50000; i ++)

{
create(i);
}
System.out.println(Time:+ Long.toString(System.currentTimeMillis() - t));
}

private void create(int i){
Project p = new Project(Project+ i);
em.persist(p);
}
}

现在,通过EL#{myBean .testInsert}有两件事情似乎很奇怪:



1)将@ Transactional-annotation移到方法create(int)我得到:


javax.persistence.TransactionRequiredException:JBAS011469:
执行此操作需要执行事务(使用
事务或扩展持久性上下文)


2)用@Transactional装饰testInsert(),该函数立即返回,但JPA仍然在后台更新数据库线。该过程需要2分钟才能完成只有50000条记录的INSERT。在这个过程中关闭Java EE应用程序服务器时,后台进程停止,因此在我看来 - testInsert()不是事务性的。



这里误会?如何正确管理交易?

解决方案

@ javax.transaction.Transactional 是在Java EE 7中引入的拦截器绑定。由CDI为您的bean注入的代理将拦截注释的方法调用以将其包装在事务中。



拦截器不适用于私有方法 - 我想这是你的例子的主要问题。


Having a simple CDI bean in session scope with an entity manager injected:

@Named("myBean")
@SessionScoped
public class MyBean implements Serializable {
    private static final long serialVersionUID = 1L;

    @Inject
    EntityManager em;
   ...

    @Transactional
    private void testInsert() {
        long t = System.currentTimeMillis();

        for (int i=1; i<50000; i++) {  
            create(i);
        }
       System.out.println("Time: " + Long.toString(System.currentTimeMillis()-t));
    }

    private void create(int i) {
        Project p = new Project("Project " + i);
        em.persist(p);
    }
}

Now, when calling the function via EL #{myBean.testInsert} there are two things that seems to be very strange:

1) Moving the @Transactional-annotation to the method create(int) I get:

javax.persistence.TransactionRequiredException: JBAS011469: Transaction is required to perform this operation (either use a transaction or extended persistence context)

2) Decorating testInsert() with @Transactional instead, the function returns instantly but JPA is still updating the database within a background thread. The process needs 2 minutes to finish INSERT of only 50000 records. When shutting down the Java EE-application server within the process, the background process stops and thus - in my opinion - testInsert() is not transactional.

What is my general misunderstanding here? How to manage transactions properly?

解决方案

@javax.transaction.Transactional is an interceptor binding introduced in Java EE 7. The proxy injected by CDI for your bean will intercept annotated method calls to wrap them in a transaction.

Interceptors do not work for private methods - I suppose that's the main problem with your example.

这篇关于CDI交易管理:@Transactional如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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