hibernate的事务配置详解和出现的问题

本文详述了一个项目中遇到的 Hibernate 事务配置问题,导致的ERROR 1205(HY000) 锁等待超时错误。通过分析事务配置,包括`tx:advice`、`tx:method`和`aop:pointcut`,揭示了事务在Service层的使用。问题根源在于定时任务未使用事务处理数据库操作。解决方案是确保所有数据库操作都在事务中进行,以维护事务特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目的Hibernate的配置文件详解和对事务和锁的一些理解

 

由于测试的时候数据库报ERROR 1205(HY000): Lock wait timeout exceeded; try restarting transaction的错误,为了解决这个问题,从查看源代码,然后对hibernate事务的配置,事务和锁的关系做了一些研究,从而发现问题的所在,以此记下,共以后参考。

出现上面的问题,锁等待超时,推出代码中的事务使用方面出了问题,查看了对事务的配置,使用了c3p0配置数据库,用标签加切面配置事务的,我们直接看事务的配置:

 


<!-- 配置事务管理器 -->
<bean id="transactionManager"
     
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property
name="sessionFactory"ref="sessionFactory" />
</bean>

<!-- 配置事务增强处理Bean,指定事务管理器 -->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
   
<!-- 配置详细事务处理语义 -->
   
<tx:attributes>
        <
tx:methodname="insert*" propagation="REQUIRED"/>
        <
tx:methodname="update*" propagation="REQUIRED"/>
        <
tx:methodname="delete*" propagation="REQUIRED"/>

        <
tx:methodname="get*" propagation="SUPPORTS"read-only="true" />
        <
tx:methodname="find*" propagation="SUPPORTS"read-only="true" />
        <
tx:methodname="select*" propagation="SUPPORTS"read-only="true" />
        <
tx:methodname="load*" propagation="SUPPORTS"read-only="true" />

       
<!-- 其他采用默认事务方式 -->
       
<tx:method name="*"/>

    </
tx:attributes>
</
tx:advice>

<
aop:config>
    <
aop:pointcutid="transactionPointcut"
                 
expression="execution(* com.xxxx.cn.service..*.*(..))"/>
   
<!-- 指定在txAdvice切入点应用txAdvice事务增强处理 -->
    <aop:advisor pointcut-ref="transactionPointcut"
                
advice-ref="transactionAdvice"/>
</
aop:config>

 

 

 

(1)  tx:attribute标签所配置的是作为事务的方法的命名类型。

         如<tx:method name="save*"propagation="REQUIRED"/>

        其中*为通配符,即代表以save为开头的所有方法,即表示符合此命名规则的方法作为一个事务。

 

        propagation="REQUIRED"代表支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

(2)   aop:pointcut标签配置参与事务的类,由于是在Service中进行数据库业务操作,配的应该是包含那些作为事务的方法的Service类。

      Pointcut的expression的详解:

       expression=" execution(*com.xxxx.cn.service..*.*(..))"

       其中第一个*代表返回值,第二*代表service包下类,第三个*代表方法名, service..两点代表service包及其子包 “(..)”代表方法参数。

(3)  aop:advisor标签就是把上面我们所配置的事务管理两部分属性整合起来作为整个事务管理。

 

通过对上面的事务的配置我们可以得出,在包com.xxxx.cn.service包及其子包下的以insert,update,delete,get,find,select,load开头的方法作为一个事务,及具有事务的特性。其他的方法都不具有事务特性。

 

然后我们的问题就出在这里,我们一般都是service层调用dao层,(dao层没有设置事务),而我们有两个定时任务,调用了service层里的一个service,但里面的方法都不具有事务特性(因为不符合事务方法名),但对数据库的操作是直接调用dao层操作数据库的,所以这些操作都是没有事务特性的。好在对数据的更改都调用了flush方法,所以也没出什么问题。

     当定时任务的数据库的数据做更改锁住表的时候,前台操作又触发了对数据的删除操作(事物特性)就发生时,ERROR 1205 (HY000): Lock wait timeout exceeded; try restartingtransaction

            修改方法:把定时任务的对数据库的操作调用service,保证所有对数据库的操都有事务特性。

事务和锁的关系:

事务有四个特性,原子性,一致性,隔离性,持久性。

其中锁是用于解决隔离性的一种机制。事务的隔离级别通过锁的机制来

实现。另外锁有不同的粒度,同时事务也是有不同的隔离级别。理解锁和事务的关系,对于调试关于锁的错误有一定的帮助,关于锁和事务的其他性能,请自己扩展。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值