Spring托管事务,EclipseLink JPA,自定义隔离级别 [英] Spring managed transactions, EclipseLink JPA, custom isolation level

查看:171
本文介绍了Spring托管事务,EclipseLink JPA,自定义隔离级别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I suspect this one is embarrassing an I am doing it wrong in a terrible way, but please bear with me.

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

I have a Spring application with Spring-managed transactions. It uses EclipseLink JPA. I have a method which does a findByNativeQuery() followed by a merge(). I need this to happen in a real SERIAL transaction isolation level. I tried adding @Transactional(isolation=Isolation.SERIALIZABLE)

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

This doesn't work because org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect#beginTransaction does not support any transaction isolation level but the default. So then I tried getting to UnitOfWork internals of ElcipseLink and starting/comitting my own transactions, but then I get an error:

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

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

Which of course makes sense... but what do I do??

推荐答案

我给了一个尝试这个,但我不完全确定解决方案。我从这篇博客并将其改编为EclipseLink。以下是代码:

I've given a try to this, but I am not completely sure of the solution. I've taken the code from this blog and adapted it for EclipseLink. Here's the code:

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隔离交易已启动,但需要对其进行正确测试以确认其有效。

I'm seeing the SERIALIZABLE isolation being logged when the transaction is initiated, but this needs to be tested properly to confirm it works.

这篇关于Spring托管事务,EclipseLink JPA,自定义隔离级别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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