JPA更新查询 - 为什么我的交易不起作用?

Ala*_*ect 2 jpa derby eclipselink

我在JavaDB(Derby)编写事务时遇到了性能问题.每笔交易花费超过500毫秒,我每天可能有数十万.我期待在MySql上部署,我不知道我是否会遇到同样的问题,但我试图在尝试之前提高Derby的性能.

一个事务涉及更新一串记录 - 多达6个如下:

public void update(List<Tally> list) {
    try {
        utx.begin();
        for (Tally tally : list) em.merge(tally);
        utx.commit();
    // etc
Run Code Online (Sandbox Code Playgroud)

我想看看UPDATE查询是否能更好地工作,因为JPA不必跟踪更新和组成SQL查询的列(附带问题:这是一个好理论吗?)

所以我编写了一个看起来像这样的命名查询:

@NamedQuery(name="TallyUpdate",
   query="UPDATE Tally t SET t.vote = t.vote + 1 WHERE t.id IN :idSet"
Run Code Online (Sandbox Code Playgroud)

这样操作:

@PersistenceContext protected EntityManager   em;
@Resource           protected UserTransaction utx;    
public void incrementVote(List<Long> idList) {
    Query q = em.createNamedQuery("TallyUpdate");
    q.setParameter("idSet", idList);
    try {
        utx.begin();
        q.executeUpdate();
        utx.commit();
    //etc
Run Code Online (Sandbox Code Playgroud)

THE 的executeUpdate()调用总是抛出一个异常:

SEVERE: javax.persistence.TransactionRequiredException: executeUpdate is not supported for a Query object obtained through non-transactional access of a container-managed transactional EntityManager
    at com.sun.enterprise.container.common.impl.QueryWrapper.executeUpdate(QueryWrapper.java:225)
Run Code Online (Sandbox Code Playgroud)

JPA实现是EclipseLink 2.3.0

这个词 - 沙拉例外意味着什么,我应该如何运行更新?

结果发布:

我确实在utx.begin()调用之后将createnamedQuery()调用移动,并且更新开始工作.我不知道为什么,但我现在要用它来运行它.

关于相对表现还没有结果,但我上面的帖子有误导性.当计算投票时,它以大约24-36种不同的方式计算,而不是6.因此,对原始update()方法(使用merge())有六次调用,每种方法都有一个大约6条记录的列表.这个调用集合需要超过500毫秒.如果Tally表是空的,那么该基准测试只有大约27ms,这大约是我希望看到的速度.当表填充到50,000行或更多行时,我看到500ms +数字.

如果有人对我发布我最终结果的结果感兴趣,请评论说.

PS这是一个在GlassFish下运行的JSF应用程序,而不是EJB.我不确定这与性能有关.

Shi*_*gon 5

由于你有一个容器管理实体管理器,我猜你有把东西注入到EJB中.因为这意味着事务由容器管理,即您不需要在代码中明确地启动它们.默认情况下,事务在EJB方法启动时启动,在该方法完成时结束.这适用于无状态EJB.对于有状态EJB,事务可以跨越多个方法调用,并在调用EJB"destroy"方法时结束.所以你应该决定:你要么使用一个容器管理的实体管理器(一个注入EJB,就像你在这里一样),你让容器管理trasactions(通过JTA),或者你做一个应用程序管理的实体管理器,你处理自己在代码中的事务.

关于性能,Apache的人说Derby在某些场景中对于生产,匹配甚至超过MySQL和PostgreSQL非常有用,正如你在这个Apache文档中看到的那样:

http://home.online.no/~olmsan/publications/pres/apachecon05us/apachecon05.pdf

凭借一粒盐,Derby因其表现而闻名世界.甚至这个文档也表明在某些情况下Derby比MySQL慢得多.德比的CPU使用率也更高.

我的建议:做一个概念验证,并在该数据库上进行基准测试.如果您将在生产中使用它,那么在不同的数据库上对您的应用进行性能调整没有多大意义.