day18-事务与连接池 6.事务隔离级别与解决问题

本文详细解释了数据库事务的四种隔离级别:Read Uncommitted、Read Committed、Repeatable Read 和 Serializable 的概念及其应用场景。通过实例说明了脏读、不可重复读和幻读等问题,并探讨了这些现象在实际开发中的影响。

开两个cmd窗口,相当于两个事务。


read-uncommitted这种级别是解决不了任何问题的,它什么情况都能出现。刚才演示了脏读,再演示就出现了不可重复读。


read-committed隔离级别能解决脏读问题。

read-committed是解决了脏读的问题,但是还是出现了不可重复读的问题。

可能有的人会认为这没有问题,A事务提交commit之后我B事务读到没问题啊,这是正确的。这种情况在开发里面有时候是没有问题的有时候是有问题的。如果我现在要做报表,现在查询的数据要做成报表导出来,导成文件,例如说我做的是一个交通管理系统,我要统计这个月发生了多少起车祸,那就有问题了,第一次查八起车祸,第二次查十八起车祸,两次读取的结果不一样,因为你读取了别人提交的数据。问题是这个报表以哪个为准,第一次八起,第二次十八起,没准你第三次查又变了。不确定哪个数据为准。开发里面有时候会影响,因为你不知道用哪个数据。但是有些情况是我只是想看一下我也不想导成报表之类的,只是看一下那就无所谓了。但是有些情况就必须要求第一次和第二次查是一致的。所以不可重复读在某些情况是必须考虑的。


oralce的事务隔离级别是read-committed。不是说不可重复读是很严重的错误,至少人家oracle是允许这样的操作的,但是在某些情况下是不允许的。

不可重复读就是一个事务读取了另外一个事务提交的数据。如果现在我的数据库的事务隔离级别是Repeatable read,那么在我的事务过程中,当A事务提交了数据,B事务这边也是不更新的,保证了我每次查询都是一样的。那么在这样的数据库隔离级别下,B事务怎么能读取A事务提交的数据呢?很简单,B事务commit之后再开启事务再读取就可以了。那么这种操作就能够保证在我的这个事务过程我的数据是OK的。但是Repeatable read是不能够实时更新数据。但是这种方案在开发中有的情况下是用的到的,就好像刚才说的做报表每次查询都不一样那不就废了吗?应该每次查都一样才能做报表。


虚读和幻读演示也是麻烦的事情,因为它是强调insert。这次读和上次读的条数不一样。它是在一定概率下会出现的。


如果事务隔离级别为串行化(Serializable)它会锁表。意思是我的事务操作过程中谁也玩不了,得等到我玩完了你再玩。只有A事务commit之后B事务才能查到。但是这种操作性能很垃圾。但是那种数据要求非常严格必须得准确你就得用这种数据库事务隔离级别。

你连表操作的功能权限都没有,但是性能相当垃圾。

转载于:https://www.cnblogs.com/ZHONGZHENHUA/p/6682762.html

你的 ShardingSphere 配置整体结构是正确的,但有几个需要注意和 **可能的错误或优化点**。下面我会逐项分析并给出 **推荐修改后的完整配置**。 --- ## ✅ 你的配置分析 ```yaml spring: application: name: coupon-send-service shardingsphere: datasource: names: shard0,shard1 shard0: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sk_day09?... username: root password: 123456 initial-size: 5 min-idle: 5 max-active: 20 shard1: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sk_day10?... username: root password: 123456 initial-size: 5 min-idle: 5 max-active: 20 sharding: tables: task_user: actual-data-nodes: shard$->{0..1}.task_user database-strategy: inline: sharding-column: user_id algorithm-expression: shard$->{user_id % 2} default-data-source-name: master ``` --- ## ⚠️ 存在的问题 ### 1. `default-data-source-name: master` 不合理 你配置了两个数据源:`shard0` 和 `shard1`,但没有 `master` 数据源。 - `default-data-source-name` 的作用是:**当 SQL 没有命中任何分片策略时,默认使用的数据源** - 如果你没有定义 `master` 数据源,启动会报错: ``` Cannot find data source in sharding rule, data source name: master ``` ✅ **解决方式**: - 如果你想让 `shard0` 或 `shard1` 成为默认数据源,应将其命名为 `master`,或修改 `default-data-source-name` 为你实际的数据源名(如 `shard0`) --- ### 2. Druid 配置方式可能不生效 ShardingSphere-JDBC 的 Spring Boot Starter 从 5.x 开始,**不再支持直接在数据源中写 Druid 的连接池配置项**(如 `initial-size` 等),因为这些参数是 Druid 特有的,Spring Boot 无法自动识别。 ✅ **解决方式**: 你可以使用 `spring.datasource.druid` 配置块,或通过 Java 代码手动配置 Druid 数据源。 --- ## ✅ 推荐修正后的完整配置 ```yaml spring: application: name: coupon-send-service shardingsphere: datasource: names: shard0,shard1 shard0: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sk_day09?useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true username: root password: 123456 type: com.alibaba.druid.pool.DruidDataSource shard1: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sk_day10?useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true username: root password: 123456 type: com.alibaba.druid.pool.DruidDataSource rules: sharding: tables: task_user: actual-data-nodes: shard$->{0..1}.task_user database-strategy: inline: sharding-column: user_id sharding-algorithm-name: db-algorithm sharding-algorithms: db-algorithm: type: INLINE props: algorithm-expression: shard$->{user_id % 2} default-data-source-name: shard0 # 修改为实际存在的数据源名 ``` --- ## ✅ 补充说明 | 项目 | 说明 | |------|------| | `default-data-source-name` | 必须是你在 `datasource.names` 中定义的名称 | | `sharding-column` | 分片字段,建议是 `user_id` 这种整型字段 | | `algorithm-expression` | 分片表达式,确保 `shard0` 和 `shard1` 存在 | | `type: com.alibaba.druid.pool.DruidDataSource` | 可以保留,但 Druid 的参数建议通过 Java 配置 | --- ## ✅ 扩展建议:手动配置 Druid 数据源 Bean(更可靠) ```java @Configuration public class DataSourceConfig { @Bean public DataSource dataSource() { return ShardingSphereDataSourceFactory.createDataSource(loadConfig()); // 读取 shardingsphere 的 YAML 配置 } @Bean public ServletRegistrationBean<StatViewServlet> statViewServlet() { ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*"); Map<String, String> map = new HashMap<>(); map.put("loginUsername", "admin"); map.put("loginPassword", "admin"); bean.setInitParameters(map); return bean; } } ``` --- ## ✅ 总结 | 问题 | 建议 | |------|------| | `default-data-source-name` 错误 | 修改为实际存在的数据源名(如 `shard0`) | | Druid 配置无效 | 建议通过 Java 配置或 `spring.datasource.druid` 统一配置 | | 分片策略是否生效 | 确保 SQL 中包含 `user_id` 字段,且值为整数 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值