Spring事务不生效问题汇总

在实际项目开发中,经常会由于配置错误或使用不当,导致spring事务管理不生效。如下总结了几点事务不生效的情况:

1、确认创建的mysql数据库表引擎是InnoDB,MyISAM不支持事务。
2、确认调用的类是由spring容器管理的代理类。
AopUtils.isAopProxy(Object object)
AopUtils.isCglibProxy(Object object) //cglib
AopUtils.isJdkDynamicProxy(Object object) //jdk动态代理
<aop:config proxy-target-class="true" />可强制cglib代理
  • 1
  • 2
  • 3
  • 4
3、调用的方法必须是public,否则事务不起作用。这一点由Spring的AOP特性决定的。
4、spring切点是否配置错误,或使用了springmvc,可能是context:component-scan重复扫描引起的。
5、抛出一个runtimeException才能回滚,Spring使用声明式事务处理,默认情况下,如果被注解的数据库操作方法中发生了unchecked异常,所有的数据库操作将rollback;如果发生的异常是checked异常,默认情况下数据库操作还是会提交的。
Transactional的异常控制,默认是Check Exception 不回滚,unCheck Exception回滚
如果我想check异常也想回滚怎么办,注解上面写明异常类型即可@Transactional(rollbackFor=Exception.class) 类似的还有norollbackFor,自定义不回滚的异常

6、Spring的事务传播策略在内部方法调用时将不起作用。
public int save(String name, int age) throws Exception {
        insert(name, age);
        return 1;
    }
    @Transactional
    public void insert(String name, int age){
        jdbcTemplate.update("insert into user(id,name,age)values(1,'"+name+"',"+age+")");
        jdbcTemplate.update("insert into user(id,name,age)values(2,'"+name+"',"+age+")");
        jdbcTemplate.update("insert into user(id,name,age)values(1,'"+name+"',"+age+")");
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Spring事务的传播机制: 
Propagation支持7种不同的传播机制: 
REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。 
SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。 
NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。 
REQUIRESNEW:总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。 
MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。 
NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常 
NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。


<think>好的,我现在需要帮用户总结他们的项目需求和数据库设计。首先,用户的项目是一个医共体内的药品耗材管理系统,涉及中心库房和二级库房,关联科室,还有供应商、厂家、药品字典等信息。功能包括采购、入库、库存、配送、结算等全流程管理,还有不良反应监测。 首先,我得理清业务模块。用户提到了供应商管理、条码管理、采购管理等等,这些模块需要拆解出来。每个模块的功能点要明确,比如供应商管理需要维护信息和证件,采购管理包括申请、计划、订单等步骤。 接下来是数据库设计。考虑MySQL表结构,可能需要几十张表。主表应该包括库房、科室、供应商、厂家、药品字典等基础信息。然后是和业务流程相关的表,比如采购申请、订单、入库单、出库单等。每个业务流程需要关联相应的基础表,比如采购订单关联供应商和库房。 要注意的是库房分级,中心库房和二级库房,可能需要parent_id字段来表示层级关系。科室关联库房,一个库房可能对应多个科室,或者一个科室对应多个库房?这里可能需要中间表来处理多对多关系。 证件维护部分,供应商和厂家都有相关证件,可能需要单独的表存储证件信息,比如证件类型、有效期、文件路径等,并关联到供应商或厂家表。药品字典也需要证件,可能同样结构。 业务流程表如采购订单,需要关联供应商、库房、药品,记录数量和状态。入库和出库要跟踪库存变化,库存管理表需要记录每个药品在不同库房的实时数量,考虑用库存ID、药品ID、库房ID、数量、有效期等字段。 库存预警可能需要触发器或者定时任务检查库存量是否低于阈值。价格管理涉及调价记录,需要历史价格信息,所以价格表要有生效时间和失效时间。 配送管理涉及到调拨单,记录从哪个库房到哪个库房,以及配送状态。盘点表需要记录盘点的结果,差异处理情况。 不良反应监测可能需要单独的表,记录药品、医疗器械的不良反应事件,关联到具体的产品和上报信息。 还有用户提到的统计分析,可能需要汇总多个表的数据,设计一些视图或者定时统计表来提高查询效率。 权限管理也是关键,不同角色的用户(如库管、采购员、财务)需要不同的数据访问权限,可能需要用户表、角色表、权限表等。 在表结构设计时,要注意外键约束,确保数据一致性。比如采购订单的supplier_id外键关联供应商表,确保每个订单都有有效的供应商。 索引方面,高频查询的字段如药品名称、供应商名称、订单编号等需要加索引,优化查询速度。分区表可能用于大型数据表,比如库存流水表按时间分区。 事务处理方面,入库和出库操作需要保证原子性,避免数据不一致。比如出库时减少库存,同时生成出库记录,这两个操作要在一个事务里。 最后,文档整理,ER图可以帮助用户理解表之间的关系,字段注释和说明文档也是必要的,方便后续开发和维护。 可能遗漏的点:条码管理如何实现,是否需要单独的条码表,每个药品或耗材有唯一条码,关联到库存项。或者条码作为库存表的一个字段? 还有调价历史,价格变动可能需要记录每次调价的时间和操作人,方便审计。 总之,需要详细梳理每个业务模块的数据流,确保表结构覆盖所有功能点,同时保持扩展性和性能。</think>### 一、业务模块总结 根据需求,系统需覆盖以下核心业务模块: 1. **基础数据管理** - 库房管理(中心库房、二级库房,支持关联科室) - 科室信息维护 - 供应商/厂家信息及证件管理(含资质有效期监控) - 基础药品/耗材字典维护(含分类、规格、效期规则) - 条码管理(一物一码,支持扫码操作) 2. **供应链全流程管理** - **采购流程**:申请 → 计划 → 订单 → 发票 → 应付账款 - **库存流程**:入库 → 移库 → 退库 → 调拨 → 盘点 → 出库 - **财务流程**:结算 → 付款 → 调价 → 成本核算 - **配送跟踪**:配送单生成 → 状态追踪 → 签收确认 3. **监测与预警** - 效期/库存量/安全库存预警 - 药品/器械不良反应上报与统计 - 供应链全链路数据追溯 4. **统计分析** - 库存周转率分析 - 供应商绩效评估 - 采购价格趋势分析 --- ### 二、数据库核心表设计建议(MySQL) #### 1. 基础信息表 ```sql /* 库房表 */ CREATE TABLE `warehouse` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(50) NOT NULL, /* 库房名称 */ `type` TINYINT NOT NULL COMMENT '1-中心库房 2-二级库房', `parent_id` INT COMMENT '上级库房ID', `contact_info` VARCHAR(100) /* 联系方式 */ ); /* 科室关联表(多对多) */ CREATE TABLE `warehouse_dept` ( `warehouse_id` INT, `dept_id` INT, PRIMARY KEY (`warehouse_id`, `dept_id`) ); /* 供应商表 */ CREATE TABLE `supplier` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(100) NOT NULL, `license_no` VARCHAR(50) COMMENT '营业执照号', `cert_expiry` DATE COMMENT '资质到期日', `is_blacklist` TINYINT DEFAULT 0 /* 是否黑名单 */ ); /* 药品字典表 */ CREATE TABLE `drug` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `code` VARCHAR(20) UNIQUE NOT NULL, /* 药品编码 */ `name` VARCHAR(100) NOT NULL, `spec` VARCHAR(50) COMMENT '规格', `unit` VARCHAR(10) COMMENT '单位', `is_high_value` TINYINT DEFAULT 0 /* 是否高值耗材 */ ); ``` #### 2. 业务流程表 ```sql /* 采购订单表 */ CREATE TABLE `purchase_order` ( `id` VARCHAR(30) PRIMARY KEY COMMENT 'PO2024030001', `supplier_id` INT NOT NULL, `warehouse_id` INT NOT NULL COMMENT '收货库房', `total_amount` DECIMAL(12,2), `status` TINYINT DEFAULT 1 COMMENT '1-待审核 2-已发货 3-已完成', FOREIGN KEY (`supplier_id`) REFERENCES `supplier`(`id`) ); /* 库存流水表 */ CREATE TABLE `inventory_transaction` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `drug_id` INT NOT NULL, `warehouse_id` INT NOT NULL, `batch_no` VARCHAR(30) COMMENT '批次号', `expiry_date` DATE COMMENT '有效期', `qty` INT NOT NULL, `transaction_type` TINYINT COMMENT '1-入库 2-出库 3-调拨', `ref_id` VARCHAR(30) COMMENT '关联单据号', KEY `idx_batch` (`batch_no`) ); /* 价格历史表 */ CREATE TABLE `price_history` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `drug_id` INT NOT NULL, `price` DECIMAL(10,2), `effective_date` DATE NOT NULL, FOREIGN KEY (`drug_id`) REFERENCES `drug`(`id`) ); ``` #### 3. 预警与监测表 ```sql /* 库存预警规则表 */ CREATE TABLE `inventory_alert` ( `drug_id` INT PRIMARY KEY, `min_stock` INT COMMENT '最低库存阈值', `max_stock` INT COMMENT '最高库存阈值', FOREIGN KEY (`drug_id`) REFERENCES `drug`(`id`) ); /* 不良反应报告表 */ CREATE TABLE `adverse_event` ( `id` BIGINT PRIMARY KEY AUTO_INCREMENT, `drug_id` INT, `reporter` VARCHAR(50) COMMENT '上报人', `event_desc` TEXT NOT NULL, `report_time` DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` --- ### 三、关键设计要点 1. **库房层级处理** - 通过`warehouse.parent_id`实现多级库房结构 - 库存调拨时需校验源库房与目标库房层级关系 2. **事务一致性** - 出入库操作使用数据库事务,确保库存增减与流水记录原子性 3. **性能优化** - 高频查询字段(如药品编码、批次号)添加索引 - 历史数据归档策略(如3年以上库存流水转存备份库) 4. **扩展性设计** - 使用字典表管理业务类型(如`transaction_type`) - 预留自定义字段满足未来需求变化 --- ### 四、辅助建议 1. **技术选型** - 使用Spring Cloud Alibaba实现微服务架构 - 集成ELK实现操作日志分析 - 采用Redisson分布式锁处理并发库存操作 2. **对接规范** - 通过FHIR标准与全民健康信息平台对接 - 对外提供RESTful API支持第三方系统集成 需要进一步细化具体字段或业务流程实现逻辑,可补充说明需求细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值