定义:
什么是事务,事务是逻辑上的一组操作,要么都执行要么都不执行。
一. 事务的四大特性(ACID)
原子性(Atomicity):事务是最小的执行单元,不可分割,事务的原子性确保动作要么都执行要么都不执行
一致性(Consistency):执行事务前后保证数据的一致性,多个事务对同一个数据的读取结果都是一样的
隔离性(Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务的数据库是独立的
持久性(Durability):事务提交之后对数据库中数据的改变是持久的,即使数据库发生了故障也不应该对其有任何影响
二. 并发事务带来的问题
当多个事务并发运行时,不可避免的存在多个事务对同样的数据进行修改操作,那这个时候就容易出现下列问题:
1. 脏读:当一个事务正在访问了数据 并且对数据进行了修改,这种修改还没有提交到数据库,这时另一个事务访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那这个事务访问到的数据就是“脏数据”,依据“脏数据”做的操作可能是不正确的。
2. 丢失修改:当一个事务在访问数据时,另一个事务也访问了这个数据,事务一修改了数据,事务二也修改了数据,这样提交之后事务一的修改会丢失,被称为丢失修改
3. 不可重复读:一个事务多次读同一个数据,期间这个数据可能被其他事务修改了,就会导致事务第一次跟第二次读取的数据不一致,出现两次读出相同的数据可能显示不一样的情况
4. 幻读:一个事务多次读取同一个数据,期间这个数据可能被其他事务删除或者增加,修改了数据条数,这就导致这个事务在读取同一个数据时出现了原本不存在的数据或者原先存在现在不存在的数据的情况像幻觉一样
三. 事务的隔离级别
1. 读取未提交(READ-UNCOMMITED):最低的隔离级别,允许读取未提交的数据,可能出现出现脏读、不可重复读、幻读问题
2. 读取已提交(READ-COMMITED):允许读取并发事务已经提交的数据,可以避免脏读,但是还是有可能会出现不可重复读和幻读的问题
3. 可重复读(REPEATABLE-READ):可多次读取数据 读取结果是一样的,是被自身事务所修改的,可以有效防止脏读、不可重复读的问题,不过还是有可能出现幻读的问题
4. 可串行化(SERIALIZABLE):是隔离级别最高的,完全服从CAID,各个事务之间依次执行,不存在相互影响的问题,该级别可以有效防止脏读、丢失修改、不可重复读、幻读的问题
四. spring事务机制
Spring 事务注解@Transactional
Spring事务机制是一种典型的策略模式,PlatformTransactionManager代表事务管理接口,但它并不知道到底如何管理事务,它只要求事务管理提供开始事务getTransaction(),提交事务commit()和回滚事务rollback()这三个方法,但具体如何实现则交给其实现类完成。编程人员只需要在配置文件中根据具体需要使用的事务类型做配置,Spring底层就自动会使用具体的事务实现类进行事务操作,而对于程序员来说,完全不需要关心底层过程,只需要面向PlatformTransactionManager接口进行编程即可。PlatformTransactionManager接口中提供了如下方法:getTransaction(..), commit(); rollback(); 这些都是与平台无关的事务操作。
五. spring事务传播
1. REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED)
支持当前事务,如果没有事务会创建一个新的事务
2. SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS)
支持当前事务,如果没有事务的话以非事务方式执行
3. MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY)
支持当前事务,如果没有事务抛出异常
4. REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW)
创建一个新的事务并挂起当前事务
5. NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED)
以非事务方式执行,如果当前存在事务则将当前事务挂起
6. NEVER(TransactionDefinition.PROPAGATION_NEVER)
以非事务方式进行,如果存在事务则抛出异常
7. NESTED(TransactionDefinition.PROPAGATION_NESTED)
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
六. 数据库事务
1.查询mysql全局事务隔离级别
select @@global.tx_isolation;
2.查询当前会话事务隔离级别
select @@tx_isolation;
mysql默认事务隔离级别为可重复读(REPEATABLE-READ) 可以避免脏读,不可重复读,不可避免幻读
Oracle默认事务隔离级别为读取已提交(READ-COMMITTED)可以避免脏读,不可避免面幻读和不可重复读,Oracle事务隔离最高级别为可串行化(SERIALIZABLE) 可以通过设置session来实现修改Oracle事务隔离级别
Session1> alter session set isolation_level=serializable;
Session altered
七. redis事务
1.MULTI :开启事务,redis会将后续的命令逐个放入队列中,然后使用EXEC命令来原子化执行这个命令系列。
2. EXEC:执行事务中的所有操作命令。
3. DISCARD:取消事务,放弃执行事务块中的所有命令。
4. WATCH:监视一个或多个key,如果事务在执行前,这个key(或多个key)被其他命令修改,则事务被中断,不会执行事务中的任何命令。
5. UNWATCH:取消WATCH对所有key的监视。