执行两次后续读取的事务是否需要readOnly = false?

时间:2016-04-22 22:38:14

标签: java spring hibernate transactions

背景:我在DAO中使用Hibernate,它由业务层类使用。一切都在春天自动装配。我将sessionManager连接到DAO,然后将DAO连接到业务逻辑类。

我正在使用@Transactional进行基于注释的事务管理。

我看到的错误如下:

Could not create JDBC savepoint; 
nested exception is     
java.sql.SQLException: Connection is read-only. 
Queries leading to data modification are not allowed.

抛出异常的方法是一个只读方法,按顺序包含两个只读读取。

我试图尽可能多地将代码提炼到这个演示中:

@Transactional(propagation = Propagation.REQUIRES_NEW,value="transactionManager",readOnly=true)
public Typ2 validateAndIfSoGet(String param){
    Typ blah = dao1.getTyp(param);
    if(blah!=null){
        return dao2.getTyp2(blah);
    }
    else return null;
}

您可以看到在这一个事务中,有两个读取来自不同的DAO对象。为什么Spring抱怨保存点?读取之间必须有一些保存吗?那么正确的解决方法是使其成为readOnly = false吗?或者这是一个创可贴封面修复?

提前致谢。

编辑:

getTyp()getType2()是DAO方法,它们调用相应的底层数据库以将行检索为对象。它们使用简单的Hibernate映射(1个DAO:1个表,1行:1个实体对象。)

完整的getTyp方法如下所示:

@Override
@Transactional(value="transactionManager",propagation = Propagation.NESTED,readOnly=true)
public Typ getTyp(String param){
           Typ typ = (Typ) currentSession().get(Typ.class, param);
            return typ;
}

(使用Hibernate的Session.get方法)。

getCurrentSession方法未注释。我不确定这是否与问题有关。

@Autowired
@Qualifier("sessionFactory")
private SessionFactory sessFactory;

private Session currentSession(){
    return sessFactory.getCurrentSession();
}

1 个答案:

答案 0 :(得分:1)

经过大量的环顾四周,我终于找到了问题所在。

这根本不是我所期待的。

在我的Hibernate配置中,我在

的SessionFactory中设置了一个属性
<prop key="hibernate.current_session_context_class">thread</prop>

显然,这搞砸了Spring的交易管理。我删除了这个,突然我的所有基于Spring的事务管理工作。

这是一个帮助我的相关主题。 Spring Source Discussion Thread

感谢所有人帮助您排除故障。