目录
1.微服务中数据一致性问题
2.分布式事务课程内容:
3.学习课程的成果:
4.课程实战:
微服务:
5.使用Sql实现事务:
sql:
6.使用JDBC实现事务:
java 代码:
Spring的JDBC操作和事务操作,包括事务的定义,不考虑隔离级别引发的问题
Mysql的默认事务隔离级别:可重复读(REPEATABLE_READ)
两个事务,其中一个执行的时间比较长,刚开始读了一条数据,过了一会又再读了一边,但是第二次读之前已经有另一个事务对数据做了修改并且已经提交了,那么在这个还没完成的读数据的事务中读到的是另一个事务修改之前的数据。但是如果这个事务提交了再去读取的话,那么读到的就是新数据。
即在一个事务中读多次读到的结果应该是一样的,不管其他事务修改数据后有没有提交。一个事务对数据修改了还没有提交读到的是之前的数据,现在一个事务将数据修改了
比如这样在一个事务中修改数据:
另一个事务中读取数据:
脏读(READ_UNCOMMITTD):在一个事务中读到另一个事务未提交的数据。
读已提交(READ_COMMITTED):读已提交和可重复读的区别?比如说在第一个事务中修改数据还未提交,第二个事事务肯定读到原来的数据,但是当第一个事务提交了,第二个事务就会读到提交的数据,即第二个事务中多次读到的结果不一致。
线性读(SERIALIZABLE):所有的事务操作都是线性的。可以用来锁数据。
用代码实现的话,第一个事务中如果没有提交,那么第二个的代码没有加事务,读取会进行但是修改的语句会像会像断点一样等待而不会执行。等待第一个数据执行完成第二个的修改才会继续执行。
还是上面的情况 只不过我第二个会话中的修改是基于查询第一个事务未提交的修改结果来修改,这样第一个事务没有提交,第二个会话还是会像上面一样停住,但是执行完了数据不符合预期,因为基于查询的结果修改,这个结果是读到第一个事务未提交的。那么第二个会话如果加上事务的话,这种情况依然改变不了。
那么怎么解决呢?可以使用for update 但是直接使用会锁住表,所以必须在之前加上条件 where id =1,2.. 这个id必须是索引,这样就锁住一条数据。