SSH报错org.hibernate.TransactionException: nested transactions not supported 我会带着你远行 2023-10-18 22:12 54阅读 0赞 ### org.hibernate.TransactionException: nested transactions not supported ### 错误说明:出现这个错误是因为事务嵌套的问题!!! 代码如下: private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @SuppressWarnings("unchecked") @Override public List<TbUsers> Login(String account,String password) { Session session = null; Transaction tran = null; List<TbUsers> list = null; try{ if(sessionFactory!=null){ System.out.println("拿到session"); } /* * openSession是否开始事务均正常执行 * getCurrentSession只有不开始事务才正常 */ //session = sessionFactory.openSession(); session = sessionFactory.getCurrentSession(); tran = session.beginTransaction();//开始事物 String hqlString = "from TbUsers users where users.account = ?0 and users.password= ?1"; Query query = session.createQuery(hqlString); query.setString("0", account); query.setString("1", password); list = query.list(); tran.commit(); return list; } catch(Exception e){ e.printStackTrace(); } finally{ //openSession时需要手动关闭一下 //session.close(); } return list; } 具体原因暂时不明,用spring4来管理hibernate4的sessionFactory,applicationContext.xml完整配置如下;此配置下:**如果用getCurrentSession获取session会导致事务嵌套发生,网上绝大多数说必须开启事务不知道怎么 来的 ;而openSession是否开启事务都能执行,但是最后必须手动关闭:session.close();否则会连接占满** <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 配置注解自动扫描的包 --> <!-- <context:component-scan base-package="com.ssh.*"></context:component-scan> --> <!-- 配置数据源 --> <context:property-placeholder location="classpath:c3p0-db.properties" /> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driverClass}" /> <property name="jdbcUrl" value="${jdbc.jdbcUrl}" /> <property name="user" value="${jdbc.user}" /> <property name="password" value="${jdbc.password}" /> <property name="maxPoolSize" value="4"></property> <!-- 连接池中保留的最小连接数,默认为:3 --> <property name="minPoolSize" value="2" /> <!-- 初始化连接池中的连接数,取值应在minPoolSize与maxPoolSize之间,默认为3 --> <property name="initialPoolSize" value="2" /> <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。默认值: 0 --> <property name="maxIdleTime" value="60"></property> <!-- 当连接池连接耗尽时,客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒。默认:0 --> <property name="checkoutTimeout" value="3000" /> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。默认值: 3 --> <property name="acquireIncrement" value="2" /> <!--定义在从数据库获取新连接失败后重复尝试的次数。默认值: 30 ;小于等于0表示无限次 --> <property name="acquireRetryAttempts" value="0" /> <!--重新尝试的时间间隔,默认为:1000毫秒 --> <property name="acquireRetryDelay" value="1000" /> <!--关闭连接时,是否提交未提交的事务,默认为false,即关闭连接,回滚未提交的事务 --> <property name="autoCommitOnClose" value="false"></property> <!--每60秒检查所有连接池中的空闲连接。默认值: 0,不检查 --> <property name="idleConnectionTestPeriod" value="60"></property> <!--c3p0全局的PreparedStatements缓存的大小。如果maxStatements与maxStatementsPerConnection均为0,则缓存不生效,只要有一个不为0,则语句的缓存就能生效。如果默认值: 0 --> <property name="maxStatements" value="100"></property> <!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。默认值: 0 --> <property name="maxStatementsPerConnection" value="0"></property> </bean> <!-- 生成SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <!-- 使用某个数据源生成SessionFactory --> <property name="dataSource" ref="dataSource"></property> <!-- hibernate 配置文件的路径 --> <property name="configLocation" value="classpath:hibernate.cfg.xml"></property> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 登录 --> <bean id="logDaoImpl" class="demo.ssh.daoImpl.LogDaoImpl"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <bean id="logServiceImpl" class="demo.ssh.serviceImpl.LogServiceImpl"> </bean> <bean id="LogAction" class="demo.ssh.action.LogAction"> </bean> <!-- _________________________________________________________________________________________________________________ --> <!-- 基于注解的事务,当注解中发现@Transactional时,使用id为“transactionManager”的事务管理器 --> <!-- 如果没有设置transaction-manager的值,则spring以缺省默认的事务管理器来处理事务,默认事务管理器为第一个加载的事务管理器 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 声明式容器事务管理 ,transaction-manager指定事务管理器为transactionManager --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="find*" read-only="true" /> <tx:method name="get*" read-only="true" /> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="test*" propagation="REQUIRED" /> <tx:method name="*Transaction" propagation="REQUIRED" /> <tx:method name="*" propagation="REQUIRED" /> </tx:attributes> </tx:advice> <!-- 只对业务逻辑层实施事务 --> <aop:config expose-proxy="true"> <aop:pointcut expression="execution(* demo.ssh.daoImpl.*.*(..))" id="txPointcut" /> <!-- Advisor定义,切入点和通知分别为txPointcut、txAdvice --> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" /> </aop:config> </beans> hibernate.cfg.xml配置如下: <?xml version='1.0' encoding='utf-8'?> <!-- <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-4.0.dtd"> --> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.c3p0.idle_test_period">300</property> <property name="hibernate.c3p0.acquire_increment">4</property> <property name="hibernate.c3p0.validate">true</property> --> <!-- hibernate配置信息 --> <!-- SQL dialect 方言,用于配置生成针对哪个数据库的--> <!-- 方言类,Hibernate提供的,用于封装某种特定的 --> <property name="dialect">org.hibernate.dialect.SQLServer2008Dialect</property> <!-- 生成的sql是否打印到控制台 --> <!-- 打印的sql是否进行格式化 --> <property name="show_sql">false</property> <property name="format_sql">false</property> <!-- <property name="hbm2ddl.auto">update</property> --> <property name="connection.autocommit">true</property> <!-- hibernate.generate_statistics属性,该属性提供了Hibernate应用中操作的统计信息 --> <property name="generate_statistics">false</property> <property name="autoReconnect">true</property> <property name="max_fech_depth">5</property> <property name="jdbc.batch_size">50</property> <property name="jdbc.fetch_size">100</property> <property name="current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</property> <!-- 在配置文件中关联映射文件 --> <mapping resource="demo/ssh/entity/TbUsers.hbm.xml"/> </session-factory> </hibernate-configuration>
还没有评论,来说两句吧...