Spring事务失效的几种原因
数据库引擎不支持事务
在MySQL数据库中有几种引擎(InnoDB,MyISAM,Memory等等),仅仅InnoDB支持事务,如果数据库底层都不支持事务的话,那么再怎么折腾都是白搭.
@transactional加在private方法上
@Transactional只能加在public方法上,如果需要在private方法中加入事务,可以使用Aspect配transactionManager使用.
本类方法调本类另一个方法
例如:
@Service publicclassUserServiceImplimplementsUserService{ @Transactional publicvoidupdate(Useruser){ //check updateUserInfo(user); } @Transactional(propagation=Propagation.REQUIRES_NEW) publicvoidupdateUser(Useruser){ //updateuser } }
@Transactional(propagation=Propagation.REQUIRES_NEW)是无效的,在Spring中是使用代理的方式实现事务,发生自身调用的时候,没有经过Spring的代理,自然事务失效.
不支持事务
@Service publicclassUserServiceImplimplementsUserService{ @Transactional(propagation=Propagation.NOT_SUPPORTED) publicvoidupdate(Useruser){ //dosomeaction } }
@Transactional(propagation=Propagation.NOT_SUPPORTED)表示如果当前存在事务就挂起,以没有事务的方式运行,主动不支持事务了,那么再怎么操作也是白搭.此处贴下Spring的传播行为:
/** *Supportacurrenttransaction,createanewoneifnoneexists. *AnalogoustoEJBtransactionattributeofthesamename. *Thisisthedefaultsettingofatransactionannotation. */ REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED), /** *Supportacurrenttransaction,executenon-transactionallyifnoneexists. *AnalogoustoEJBtransactionattributeofthesamename. *
Note:Fortransactionmanagerswithtransactionsynchronization, *PROPAGATION_SUPPORTSisslightlydifferentfromnotransactionatall, *asitdefinesatransactionscopethatsynchronizationwillapplyfor. *Asaconsequence,thesameresources(JDBCConnection,HibernateSession,etc) *willbesharedfortheentirespecifiedscope.Notethatthisdependson *theactualsynchronizationconfigurationofthetransactionmanager. *@seeorg.springframework.transaction.support.AbstractPlatformTransactionManager#setTransactionSynchronization */ SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS), /** *Supportacurrenttransaction,throwanexceptionifnoneexists. *AnalogoustoEJBtransactionattributeofthesamename. */ MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY), /** *Createanewtransaction,andsuspendthecurrenttransactionifoneexists. *AnalogoustotheEJBtransactionattributeofthesamename. *
NOTE:Actualtransactionsuspensionwillnotworkout-of-the-box *onalltransactionmanagers.Thisinparticularappliesto *{@linkorg.springframework.transaction.jta.JtaTransactionManager}, *whichrequiresthe{@codejavax.transaction.TransactionManager}tobe *madeavailabletoit(whichisserver-specificinstandardJavaEE). *@seeorg.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW), /** *Executenon-transactionally,suspendthecurrenttransactionifoneexists. *AnalogoustoEJBtransactionattributeofthesamename. *
NOTE:Actualtransactionsuspensionwillnotworkout-of-the-box *onalltransactionmanagers.Thisinparticularappliesto *{@linkorg.springframework.transaction.jta.JtaTransactionManager}, *whichrequiresthe{@codejavax.transaction.TransactionManager}tobe *madeavailabletoit(whichisserver-specificinstandardJavaEE). *@seeorg.springframework.transaction.jta.JtaTransactionManager#setTransactionManager */ NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED), /** *Executenon-transactionally,throwanexceptionifatransactionexists. *AnalogoustoEJBtransactionattributeofthesamename. */ NEVER(TransactionDefinition.PROPAGATION_NEVER), /** *Executewithinanestedtransactionifacurrenttransactionexists, *behavelikePROPAGATION_REQUIREDelse.ThereisnoanalogousfeatureinEJB. *
Note:Actualcreationofanestedtransactionwillonlyworkonspecific *transactionmanagers.Outofthebox,thisonlyappliestotheJDBC *DataSourceTransactionManagerwhenworkingonaJDBC3.0driver. *SomeJTAprovidersmightsupportnestedtransactionsaswell. *@seeorg.springframework.jdbc.datasource.DataSourceTransactionManager */ NESTED(TransactionDefinition.PROPAGATION_NESTED);
异常被catch
@Service publicclassUserServiceImplimplementsUserService{ @Transactional publicvoidupdate(Useruser){ try{ }catch(Exceptione){ log.error(e.getMessage(),e); } } }
触发回滚的操作是被接收到异常,一般我们会在@Transactional后面加上rollbackFor或者noRollbackForClassName来指明触发回滚的异常,但是如果在代码中给catch了异常,那么对于Spring代理来说就这个方法从头到尾都没有问题,自然不会触发回滚.
异常类型错误
@Service publicclassUserServiceImplimplementsUserService{ @Transactional publicvoidupdate(Useruser){ try{ }catch(Exceptione){ log.error(e.getMessage(),e); thrownewException(e.getMessage()); } } }
以上方式thrownewException(e.getMessage());事务也是无效的,主要原因是事务回滚的条件是throw运行时异常(RunTimeException).如果需要其他异常也回滚,需要在@Transactional后面加上rollbackFor或者noRollbackForClassName来指明触发回滚的异常.
没有被Spring管理
不在Spring环境下,自然不受Spring的管理,事务管理器也当然失去了作用.
没有配置TransactionManager
需要对当前数据源配置事务管理器,尤其是在多数据源的情况下.
以上就是Spring事务失效的几种原因的详细内容,更多关于Spring事务失效的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。