背景
- 为什么有事务的概念?
- 事务的基础概念是什么?
- 事务在MySQL中是怎么回事?
- 事务在Spring中是怎么回事?
过程
-
事务的来源
张三要转钱给李四。在这个过程中会有多个步骤,查询张三的余额,张三做减法并且更新余额,而李四做加法并更新余额。
上面描述的过程,必须要保证是一个整体,要么都失败,要么都成功,不允许部分成功。
为了保证这样的逻辑。于是引出了事务这样的概念。
-
事务的基础概念
事务:保证一组数据库操作,要么全部成功,要么全部失败。
事务:有4大性质。ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性)
原子性: 一些列的操作,一些列步骤都是一个整体。
一致性: 执行前后一定要保证数据的合理性。
隔离性:事务与事务之间是相互独立的。这里的隔离性就是描述了事务之间的隔离级别。
持久性: 把最终的结果的数据持久化到数据库中或者磁盘上。
-
MySQL中的隔离级别 (事务的基础概念隔离性的实践)
读未提交:一个事务还未提交,它做的变更能被别的事务看到。
读提交:一个事务提交之后,它做的变更才会被其他事务看到。
可重复读:一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。在可重复读隔离级别下,未提交变更对其他事务也是不可见的。
串行化:对同一行记录,写加写锁,读加读锁。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。
-
Spring中的Transactional的基础知识 Spring定义的七种传播行为
- REQUIRED:当前方法必须运行在事务中。如果当前事务存在,方法将会在该事务中运行。否则,会启动一个新的事务。
- SUPPORTS:当前方法不需要事务上下文,但是如果存在当前事务的话,那么该方法会在这个事务中运行。
- MANDATORY:该方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常。
- REQUIRED_NEW:当前方法必须运行在它自己的事务中。一个新的事务将被启动。如果存在当前事务,在该方法执行期间,当前事务会被挂起。如果使用JTATransactionManager的话,则需要访TransactionManager
- NOT_SUPPORTED:该方法不应该运行在事务中。如果存在当前事务,在该方法运行期间,当前事务将被挂起。如果使用JTATransactionManager的话,则需要访问TransactionManager
- NEVER:当前方法不应该运行在事务上下文中。如果当前正有一个事务在运行,则会抛出异常。
- NESTED:如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套事务可以独立于当前事务进行单独地提交或回滚。如果当前事务不存在,那么其行为与PROPAGETION_REQUIRED一样。注意各厂商对这种传播行为是有所差异的。可以参考资源管理器的文档来确认他们是否支持嵌套事务。
小结
- 总结有关事务的基础知识。
- 记录Spring定义的7种传播行为。
- Spring中的注解@Transactional在哪些情况下会失效呢?
- 代码逻辑层面其实只有锁的概念,而事务的概念和隔离级别其实是关系型数据的概念。