MySQL的事务与Spring的事务

MySQL系列文章总目录:关系型/非关系型【数据库】知识脉络


目录

为什么 MySQL要有事务?

会有哪些可能性?

MySQL事务解决哪些问题?

MySQL事务隔离级别

命令

总共有多少种事务隔离级别呢? 

 设置完mysql事务隔离级别,就不会变了吗?



为什么 MySQL要有事务?

        一个数据库,一个表,十个人来查看,十个人来写数据,再来十个人删除数据。这一番操作下来,会有哪些可能性?

会有哪些可能性?

        假如黄蓉郭靖分隔两地,又没有电话沟通(书信需要传一个月),恰巧又使用了没事物的银行数据库。

        0. 两人都到银行先看了一眼存款:500银子!

  1. 黄蓉再存500银子,心想有1000银子,郭靖在天涯那边正取200银子,黄蓉存完一看,怎么才800银子? ——脏写/更新丢失
  2. 郭靖取完银子心想还剩300银子黄蓉不会打我吧?一看余额1000银子?——幻读
  3. 郭靖揉了揉眼睛,平复了一下心情再次查看余额800银子?——不可重复读!那1000哪去了
  4. 郭靖给自己两耳光,再次查看余额800银子。——脏读!这钱还越取越多了?

这些问题的本质都是数据库的多事务并发问题,为了解决多事务并发问题,数据库设计了事务隔离机制、锁机制、MVCC多版本并发控制隔离机制,用一整套机制来解决多事务并发问题


MySQL事务解决哪些问题?

        为避免上述情况发生,我们期待什么效果(mysql默认可重复级别读效果展示)? 

        0. 两人都到银行先看了一眼存款:500银子!

  1. 黄蓉再存500银子,心想有1000银子,郭靖在天涯那边正取200银子,取不出来,系统一直转圈圈。黄蓉存完一看余额1000银子,心满意足离开!
    1. —— 原子性(保证黄蓉的操作是一个不被打扰的整体)
    2. —— 一致性(操作前操作后数据符合更改规则)
  2. 郭靖一直操作不了,急的也跟着转圈圈,终于不转圈圈了,从查看余额开始了,变成了800,郭靖心想应该是黄蓉存下了。
    1. ——隔离性(被隔离在黄蓉事务之外)
    2. ——持久性,也包含了MVCC机制

数据库的事务隔离越严格,并发副作用越小,但付出的代价也就越大,因为事务隔离实质上就是使事务在一定程度上“串行化”进行,这显然与“并发”是矛盾的。


MySQL事务隔离级别

先看看你的数据库是什么事务隔离级别?

命令

show variables like 'tx_isolation';

结果

MySQL的事务与Spring的事务_第1张图片

总共有多少种事务隔离级别呢? 

级别 脏读  不可重复读 幻读 设置命令
read uncommitted set session transaction isolation level read uncommitted/set tx_isolation='read-uncommitted'
read committed set session transaction isolation level read committed/set tx_isolation='read-committed'

repeatable read

(mysql 默认的事务级别)

set session transaction isolation level repeatable read / set tx_isolation='repeatable-read'
serializable set ssion transaction isolation leval serializable /set tx_isolation='serializable'

 注:设置之后,rollback 就会滚刚才的操作,commit就可以提交刚才的操作。

 设置完mysql事务隔离级别,就不会变了吗?

Mysql默认的事务隔离级别是可重复读,用Spring开发程序时,如果不设置隔离级别默认用Mysql设置的隔离级别,如果Spring设置了就用已经设置的隔离级别


事务的特性

无论是mysql事务还是spring事务都是有相同的特性,为事务特性:

  1. 原子性(Atomicity):事务不可分割。一系列操作为一体。
  2. 一致性(Consistency):每个操作的结果都是一样的,要么全成功,要么全失败。
  3. 隔离性(Isolation):一些列操作过程中不被其他操作干扰。
  4. 持久性(Durability):操作的结果是持久有效的。

Spring支持事务的种类

spring框架是个脚手架,也就是帮助我们编程的工具框架,自然也提供方便的实现事务的方法,spring的事务约等于是帮助我们实现数据库事务,它主要有两种使用方式。

编程式事务管理

        顾名思义,要编程,侵入性事务管理,使用TransactionTemplate或者直接使用PlatformTransactionManager,Spring推荐使用TransactionTemplate。

        每次实现个事务都要自己手动写代码实现。

声明式事务管理

        顾名思义,声明一下哪里要实现事务,spring中所谓的声明,无非就是注解,事务的注解底层由AOP来实现。只需要关心业务实现逻辑,某个方法/类需要用到事务就加上@Transactional,再做些相应配置即可。

        看着哪都比编程式事务好,唯独粒度上最小只能到方法级别,而编程式事务可以细化到代码块。


Spring实现的事务的重点有哪些呢?

既然spring是工具,那如何使用工具,工具都有哪些功能?如何用好工具,就是关心的问题了。

传播机制

使用场景/业务需求:A方法调用B方法调用..,AB..方法各自都有事务这种嵌套调用。

如何使用?当然是配置。

  • @Transactional(PROPAGATION = REQUIRED) 默认
    • 如果外层有事务,则当前事务加入到外层事务,一块提交,一块回滚。
    • 如果外层没有事务,新建一个事务执行。
  •  @Transactional(PROPAGATION = REQUES_NEW)
    • 每次都会新开启一个事务,外层事务挂起。(对mysql来讲新建一个连接并开启事务)
    • 当前事务执行完毕,恢复上层事务的执行。
  •  @Transactional(PROPAGATION = SUPPORT)
    • 如果外层有事务,则加入外层事务。
    • 如果外层没有事务,则直接使用非事务方式执行。
  • @Transactional(PROPAGATION = NOT_SUPPORT)
    • 不支持事务。
    • 如果外层存在事务则挂起,执行完当前代码,恢复外层事务。
    • 无论是否异常都不会回滚当前的代码。
  • @Transactional(PROPAGATION = NEVER)
    • 不支持外层事务,即如果外层有事务就抛出异常。
  • @Transactional(PROPAGATION = MANDATORY)
    • 如果外层没有事务,则抛出异常。
  • @Transactional(PROPAGATION = NESTED)
    • 保存状态保存点,当前事务回滚到某一个点,避免所有的嵌套事务都回滚。
    • 即各自回滚各自的,如果子事务没有把异常吃掉,引起全部回滚的。

 

你可能感兴趣的:(数据库专题,java,后端,mysql优化)