Hibernate4中使用getCurrentSession报Could not obtain transaction-synchronized Session for current thread
2015-09-17 18:20
369 查看
架个spring4+hibernate4的demo,dao层直接注入的sessionFactory,然后用getCurrentSession方法获取session,然后问题来了,直接报错:
提示无法获取当前线程的事务同步session,略微奇怪,这和事务有什么关系..然后百度一下有人说改成用openSession方法就好了,那我又百度了一下这2个方法的区别:
看起来这个getCurrentSession方法的确和事务有点关系.然后我加上事务:
然后在dao层加上@Transaction注解,再运行ok了..不过好奇驱使吧,看了一下getCurrentSession的源码(我的demo中用的spring的实现类),关键点:
然后点进去看了一下isSynchronizationActive()方法:
get方法说明:
然后再看initialValue的说明:
到此问题明了了,补充一点之前配置文件中配了事务,不过是原来那种在配置中根据方法名字来定义事务传播的方式,但是在dao中并没有继承它,故实际上是没有事务的,只有实现.而在spring的事务实现中需要判断当前线程中的事务是否同步,而没有事务的时候,那个判断是否同步的方法会因为get返回初始的null值而返回false,最终导致throw一个Could not obtain transaction-synchronized Session for current thread的异常.
综上:spring4+hibernate4,使用hibernate的api的时候需要配置事务的,如果不配置事务会导致获取当前session抛出异常.
Could not obtain transaction-synchronized Session for current thread
提示无法获取当前线程的事务同步session,略微奇怪,这和事务有什么关系..然后百度一下有人说改成用openSession方法就好了,那我又百度了一下这2个方法的区别:
(1)openSession每次打开都是新的Session,所以多次获取的Session实例是不同的,并且需要人为的调用close方法进行Session关闭。 (2)getCurrentSession是从当前上下文中获取Session并且会绑定到当前线程,第一次调用时会创建一个Session实例,如果该Session未关闭,后续多次获取的是同一个Session实例;事务提交或者回滚时会自动关闭Sesison,无需人工关闭。
看起来这个getCurrentSession方法的确和事务有点关系.然后我加上事务:
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory"> <ref bean="sessionFactory" /> </property> </bean> <tx:annotation-driven transaction-manager="transactionManager"/>
然后在dao层加上@Transaction注解,再运行ok了..不过好奇驱使吧,看了一下getCurrentSession的源码(我的demo中用的spring的实现类),关键点:
if (TransactionSynchronizationManager.isSynchronizationActive()) { Session session = this.sessionFactory.openSession(); if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { session.setFlushMode(FlushMode.MANUAL); } SessionHolder sessionHolder = new SessionHolder(session); TransactionSynchronizationManager.registerSynchronization( new SpringSessionSynchronization(sessionHolder, this.sessionFactory, true)); TransactionSynchronizationManager.bindResource(this.sessionFactory, sessionHolder); sessionHolder.setSynchronizedWithTransaction(true); return session; } else { throw new HibernateException("Could not obtain transaction-synchronized Session for current thread"); }
然后点进去看了一下isSynchronizationActive()方法:
public static boolean isSynchronizationActive() { return (synchronizations.get() != null); }
get方法说明:
Returns the value in the current thread's copy of this thread-local variable. If the variable has no value for the current thread, it is first initialized to the value returned by an invocation of the initialValue method.
然后再看initialValue的说明:
This implementation simply returns null; if the programmer desires thread-local variables to have an initial value other than null, ThreadLocal must be subclassed, and this method overridden. Typically, an anonymous inner class will be used.
到此问题明了了,补充一点之前配置文件中配了事务,不过是原来那种在配置中根据方法名字来定义事务传播的方式,但是在dao中并没有继承它,故实际上是没有事务的,只有实现.而在spring的事务实现中需要判断当前线程中的事务是否同步,而没有事务的时候,那个判断是否同步的方法会因为get返回初始的null值而返回false,最终导致throw一个Could not obtain transaction-synchronized Session for current thread的异常.
综上:spring4+hibernate4,使用hibernate的api的时候需要配置事务的,如果不配置事务会导致获取当前session抛出异常.
相关文章推荐
- 使用mdadm快速创建RAID5
- Halo,Halo 2游戏的人工智能设计讲座
- The Beauty of Capturing Faces: Rating the Quality of Digital Portraits
- Shallow heap & Retained heap
- Grails开源框架Note
- HDU 1022 Train Problem I(用栈模拟火车出入,看能否由初始顺序到达目标顺序)
- Boost库安装与使用 http://blog.csdn.net/cybertan/article/details/5770227
- 开源C/C++网络库比较 http://blog.csdn.net/langeldep/article/details/6976120
- ubuntu重啟網卡提示"Job failed while stopping"解決方法!【参考别人的信息】
- aidl理解
- 打开IDEA时报错“Failed to create JVM: error code -6”
- 【Code Forces 320A】【二进制拆分】Raising Bacteria 细胞繁殖 每天倍增
- CodeForces 579A - Raising Bacteria
- 音乐播放器-MainFragment分析1
- UVA-818 Cutting Chains (位压缩+暴力搜索)
- 严重: StandardServer.await: create[8005]:
- Failed to create a 'System.Type' from the text ' ' in wpf(无法从文本创建类型)
- AIX加入能telnet远程连接方法的帐户
- The service ‘xxx’ configured for WCF is not registered with the Autofac container
- .NET基础--Contains用法