spring 的配置:
扫描配置:
<context:component-scan base-package="com.karting">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
配置数据库源:
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}" p:maxActive="${jdbc.maxActive}" p:initialSize="${jdbc.initialSize}" p:minEvictableIdleTimeMillis="${jdbc.minEvictableIdleTimeMillis}" p:testOnBorrow="${jdbc.testOnBorrow}" p:testWhileIdle="${jdbc.testWhileIdle}" p:validationQuery="${jdbc.validationQuery}" p:removeAbandoned="${jdbc.removeAbandoned}" p:removeAbandonedTimeout="${jdbc.removeAbandonedTimeout}" p:logAbandoned="${jdbc.logAbandoned}" p:poolPreparedStatements="${jdbc.poolPreparedStatements}" p:maxOpenPreparedStatements="${jdbc.maxOpenPreparedStatements}"> </bean>
配置注解事务:
<!-- the PlatformTransactionManager --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/>
springMVC 的配置(只扫描Controller层):
<context:component-scan base-package="com.karting.controller"/>
Service的调用(Service类上有注解@Transactional):
@Transactional @Service public class AppointmentService {
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) public void testTransactional() throws Exception{ Appointment appointment = new Appointment(); appointment.setId(1); appointment.setUpdated_by("test"); appointMentDAO.insert(appointment); throw new Exception("测试事务回滚"); }
} 抛出错误后还是插入成功,没有回滚。求各位大神帮忙看下哪里有问题。
我已经排除了:
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
从你提供的配置和代码片段来看,事务管理的配置看似是正确的。但是,事务没有按预期回滚,这通常有几个常见的原因:
异常被捕获且未重新抛出:在你的testTransactional
方法中,你手动抛出了一个Exception来测试事务回滚。确保这个异常没有被上层调用者捕获并静默处理。如果异常被捕获但没有再次抛出,Spring可能不会意识到需要回滚事务。
全局事务设置:检查是否有全局的事务传播行为或默认的只读设置影响了你的事务。虽然你在testTransactional
方法上指定了readOnly = false
和propagation = Propagation.REQUIRES_NEW
,但如果存在其他AOP代理或者全局配置覆盖了这些设置,也可能导致事务不工作如预期。
数据源或JDBC驱动问题:尽管你使用的是Druid数据源,它通常支持事务管理,但某些特定的数据库驱动或配置可能导致事务不起作用。确认Druid数据源与MariaDB的兼容性,并检查是否有任何已知的问题或特殊配置需求。
Spring的事务管理器是否正确识别异常:Spring默认只在遇到未检查异常(继承自RuntimeException
)时自动回滚事务。如果你抛出的是已检查异常(即继承自Exception
而非RuntimeException
),你需要在@Transactional
注解中明确指定rollbackFor
属性来指示哪些异常类型应该触发回滚,例如:
@Transactional(rollbackFor = Exception.class)
Spring的调试日志:开启Spring的详细事务管理日志,可以帮助诊断问题。在你的日志配置中添加如下内容以获取更详细的事务处理信息:
<logger name="org.springframework.transaction" level="DEBUG"/>
这将帮助你了解事务开始、提交或回滚的具体时机以及任何相关的错误信息。
环境问题:有时候,开发、测试和生产环境之间的差异也会导致这种问题。确保所有环境的配置是一致的,包括数据库版本、连接参数等。
请逐一排查上述点,特别是第1点和第4点是最常见的原因。希望这能帮助你找到问题所在。