哪个网站专做滨水景观,软件定制开发税率是多少,综合网上购物商城,桂林最好玩的5个地方一. 事务的特性
ACID
原子性 -- 事务操作被视为一个整体 , 要么全部成功 , 要么全部失败一致性 -- 事务操作前后数据的变化是一致的隔离性 -- 事务的执行不受其他事务的影响持久性 -- 事务执行完毕会对数据永久保存
比如我们在转账的过程中 , A给B转账1000元…一. 事务的特性
ACID
原子性 -- 事务操作被视为一个整体 , 要么全部成功 , 要么全部失败一致性 -- 事务操作前后数据的变化是一致的隔离性 -- 事务的执行不受其他事务的影响持久性 -- 事务执行完毕会对数据永久保存
比如我们在转账的过程中 , A给B转账1000元 , 在转账过程会对A的余额扣减 , B的余额增加 , 这是两个过程但在一个事务中会被视为一个整体 , 不可能出现A扣减成功 , B增加失败这种情况 , 这就是事务的原子性 . 而对于一致性我们可以理解为iA减少了1000块 , 那B必然会增加1000块 , 这个数据的变化是一致的. 对应隔离性 , 也就是我们在转账的过程中 , 是不会收到其他业务操作的影响 . **面试官**事务的特性是什么可以详细说一下吗
**候选人**嗯这个比较清楚ACID分别指的是原子性、一致性、隔离性、持久性我举个例子
A向B转账500转账成功A扣除500元B增加500元原子操作体现在要么都成功要么都失败
在转账的过程中数据要一致A扣除了500B必须增加500
在转账的过程中隔离性体现在A像B转账不能受其他事务干扰
在转账的过程中持久性体现在事务提交后要把数据持久化可以说是落盘操作
二. 并发事务问题
并发事务会产生哪些问题?
脏读: 一个事务读取到其他事务还未提交的数据不可重复读: 一个事务在第一次读取某个数据的时候 , 得到一个结果 , 此时其他事务对该数据进行了修改 , 导致原事务在再次读取的时候读取的数据和第一次读取的不相同幻读: 一个数据在多次读取某个数据的过程中 , 其他事务对数据就行了增删 , 导致原事务再次读取数据获得的结果比原数据多了或者少了 , 就像出现幻觉一样
如何解决并发事务问题?
在Mysql的隔离机制当中有对上述情况就行处理的方式
Mysql的隔离机制共包含四种
读未提交 -- 上述三种问题都不能解决读已提交 -- 可以解决脏读问题可重复读 -- 可以解决脏读与不可重复读问题 , 是Mysql的默认事务隔离级别串行话 -- 上述三种问题都可以解决 , 但是其执行效率慢 , 不建议使用 面试官并发事务带来哪些问题
候选人
我们在项目开发中多个事务并发进行是经常发生的并发也是必然的有可能导致一些问题
第一是脏读 当一个事务正在访问数据并且对数据进行了修改而这种修改还没有提交到数据库中这时另外一个事务也访问了这个数据因为这个数据是还没有提交的数据那么另外一个事务读到的这个数据是“脏数据”依据“脏数据”所做的操作可能是不正确的。
第二是不可重复读比如在一个事务内多次读同一数据。在这个事务还没有结束时另一个事务也访问该数据。那么在第一个事务中的两次读数据之间由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况因此称为不可重复读。
第三是幻读Phantom read幻读与不可重复读类似。它发生在一个事务T1读取了几行数据接着另一个并发事务T2插入了一些数据时。在随后的查询中第一个事务T1就会发现多了一些原本不存在的记录就好像发生了幻觉一样所以称为幻读。
面试官怎么解决这些问题呢MySQL的默认隔离级别是
候选人解决方案是对事务进行隔离
MySQL支持四种隔离级别分别有
第一个是未提交读read uncommitted它解决不了刚才提出的所有问题一般项目中也不用这个。第二个是读已提交read committed它能解决脏读的问题的但是解决不了不可重复读和幻读。第三个是可重复读repeatable read它能解决脏读和不可重复读但是解决不了幻读这个也是mysql默认的隔离级别。第四个是串行化serializable它可以解决刚才提出来的所有问题但是由于让是事务串行执行的性能比较低。所以我们一般使用的都是mysql默认的隔离级别:可重复读
三. undo_log和redo_log
1. 什么是undo_log
undo_log是一种逻辑日志他记录的命令和原有命名是相反的 , 就比如我现在执行一条插入命令 , 在undo_log中就会保存与之逻辑相同的删除日志 , 主要用来保证事务中的原子性 , 一致性
2. 什么是redo_log
undo_log简单来说就是Mysql用来保证事务持久性所采取的一种策略 , 在mysql的事务提交过程中 , mysql需要将内存当中的数据保存到磁盘中 ,而mysql会在内存当中创建一个缓冲区 , 他不会在磁盘中直接对数据就行修改 , 而是在这个缓冲区当中修改数据再提交 , 对于mysql的数据是通过页表的形式进行保存 , 一张页表也就是代表着表中的一条数据 , 在食物提交之前会在缓冲区中查询该数据是否存在于缓存区 , 缓冲区会保存一些常用数据 , 如果数据不存在就会向磁盘中请求获取数据.
那么在缓冲区对数据进行修改之后 , 就会触发提交 , 但是在这个提交过程当中如果mysql出现故障导致宕机 , 那么我们事务的数据就会丢失 , 这种情况肯定是不被允许的. 因此mysql采用了redolog日志的方式来解决该问题
redo_log也就是当事务提交前会优先记录改事务的操作并保存到与缓冲区同级的redo_log缓冲区当中 , redo_log缓冲区在接受到该日志信息后会立即同步到磁盘的redo_log file文件中 , 该过程是通过追加方式进行保存 , 执行速度非常快 , 当服务异常宕机并出现脏页数据时 , 再重启后就会读取该日志文件更新数据
四. 分布式事务
分布式事务通常用在分布式环境对多个服务多张表的修改当中 , 在我近期的物流项目当中也是采用了seata来处理分布式事务
seata的AT模式实现原理
AT模式是优先保证数据的可用性 , 其执行流程共分为两步
第一步:
在声明了分布式注解并运行时 , seata会首先在全局事务表中注册该次事务的信息 , 对于事务中的所有分支 , 会被看做资源管理器 , 所有的资源管理器都会注册在事务管理器当中( 事务管理器是对所有资源进行统筹的 ) , 并在分支事务表中写入该事物的信息 . 在上述流程执行完毕后 , 资源管理器会对所有分支按顺序执行 , 在每个分支的执行过程中 , 会在执行前与执行后分别从数据库中查询该数据信息并记录在undo_log日志当中 , 被称为前镜像与后镜像 , 并像事务管理器报告执行情况;
第二步:
在所有分支事务执行完毕之后 , 事务管理器会对各分支执行情况就行统筹 , 如果执行出现错误 , 需要执行回滚 , seata就会通过undo_log中的前后镜像对数据进行回滚