开发者社区 问答 正文

spring durid 事务无论怎么配置都是失败! - java报错

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("测试事务回滚");
}
} 抛出错误后还是插入成功,没有回滚。求各位大神帮忙看下哪里有问题。


我已经排除了:


  1. MariaDB 的数据库引擎情况
  2. 排除了springMVC配置扫描冲突的情况

快崩溃了。。。。


展开
收起
montos 2020-06-02 22:12:17 663 分享 版权
阿里云 AI 助理回答

从你提供的配置和代码片段来看,事务管理的配置看似是正确的。但是,事务没有按预期回滚,这通常有几个常见的原因:

  1. 异常被捕获且未重新抛出:在你的testTransactional方法中,你手动抛出了一个异常,但确保这个异常没有被上层方法捕获并静默处理。如果异常被catch并且没有再次抛出或通过特定方式处理(比如AOP代理可能需要一个非检查型异常),那么Spring可能不会识别到需要回滚事务。

  2. 注解@Transactional的正确性:确认@Service类上的@Transactional注解是否生效。有时候由于类扫描、代理设置等问题,注解可能没有被正确识别。确保Spring能够代理这个Service类(通常是通过CGLIB或JDK动态代理)。

  3. 事务传播行为:你已经指定了@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW),这意味着每次调用都应该在一个新的事务中进行,并且是可写的。这看起来是正确的配置,但如果外部已经有事务存在,且其传播行为与内部事务不兼容,可能会导致一些意外情况。不过,根据你的描述,直接调用此方法应该会创建新事务。

  4. 数据源或数据库配置问题:虽然你已经排除了数据库引擎的问题,但还是建议检查DruidDataSource配置中的事务隔离级别、自动提交模式(autoCommit应为false)等设置,确保它们符合事务操作的要求。

  5. Spring的调试信息:开启详细的Spring日志,特别是关于事务管理的部分,可以帮助诊断问题。查看是否有任何有关事务开始、提交或回滚的日志输出,以及是否有任何错误或警告信息。

  6. 环境问题:确保在开发、测试和生产环境中事务配置是一致的,有时差异会导致在某些环境下事务行为不一致。

  7. 并发问题:虽然不太可能直接关联到事务不回滚,但如果你的应用在高并发下运行,确保没有其他线程或进程影响了事务的执行结果。

针对以上点,你可以逐一排查,尤其是第1点和第2点是最常见的原因。如果仍然无法定位问题,尝试使用Spring的断点或日志来跟踪事务的生命周期,看它是在哪个阶段没有按照预期工作。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答