Spring托管事务,EclipseLink JPA,自定义隔离级别

时间:2014-06-18 19:52:26

标签: java spring jpa transactions eclipselink

我怀疑这是令人尴尬的,我以一种可怕的方式做错了,但请耐心等待。

我有一个Spring应用程序,使用Spring管理的事务。 它使用EclipseLink JPA。 我有一个方法可以findByNativeQuery()后跟merge()。我需要在真正的SERIAL事务隔离级别中实现这一点。 我尝试添加 @Transactional(isolation=Isolation.SERIALIZABLE)

这不起作用,因为org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect#beginTransaction 不支持任何事务隔离级别,但默认值。 那么我尝试使用ElcipseLink的UnitOfWork内部并开始/编写我自己的事务,但后来我收到一个错误:

"java.lang.IllegalStateException : Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead

这当然有道理......但我该怎么办?

3 个答案:

答案 0 :(得分:6)

我试过这个,但我不完全确定解决方案。我从this blog获取了代码,并将其改编为EclipseLink。这是代码:

package com.byteslounge.spring.tx.dialect;

import java.sql.SQLException;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;

import org.eclipse.persistence.sessions.UnitOfWork;
import org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;

public class CustomEclipseLinkJpaDialect extends EclipseLinkJpaDialect {

    private static final long serialVersionUID = 1L;

    private boolean lazyDatabaseTransaction = false;

    @Override
    public void setLazyDatabaseTransaction(boolean lazyDatabaseTransaction) {
        this.lazyDatabaseTransaction = lazyDatabaseTransaction;
    }

    @Override
    public Object beginTransaction(final EntityManager entityManager,
            final TransactionDefinition definition)
            throws PersistenceException, SQLException, TransactionException {

        UnitOfWork uow = (UnitOfWork) getSession(entityManager);
        uow.getLogin().setTransactionIsolation(definition.getIsolationLevel());

        entityManager.getTransaction().begin();
        if (!definition.isReadOnly() && !lazyDatabaseTransaction) {
            uow.beginEarlyTransaction();
        }

        return null;
    }
}

我发现启动交易时会记录SERIALIZABLE隔离,但需要对其进行正确测试以确认其有效。

答案 1 :(得分:3)

Spring 4.1.2中添加了对自定义隔离级别的支持EclipseLinkJpaDialect

答案 2 :(得分:0)

您可以参考

“要使用EclipseLink实现可序列化的事务隔离,我们建议您使用隔离的客户端会话,如下所示:

将数据库事务隔离配置为可序列化。 将对象配置为隔离(请参阅在项目级别配置缓存隔离或在描述符级别配置缓存隔离)。 使用UnitOfWork方法beginTransactionEarly(请参阅工作单元方法beginTransactionEarly)。 如果您只关心可序列化的写入方面,那么乐观锁定就足够了。“

http://docs.oracle.com/middleware/1212/toplink/OTLCG/cache.htm或通过 http://docs.oracle.com/middleware/1212/toplink/OTLCG/cache.htm 如果任何隔离级别符合您的要求