原子性、一致性、隔离性、持久性
1、原子性:(通过undo 日志(回滚日志)实现)
事务的原子性是指事务必须是一个院子的操作序列单元,就是各项操作在一次执行中,要么全部成功,要么全部失败;只要任何一项操作失败,都会导致整个事务失败,其他已经执行的操作,都将被撤销回滚;只有所有的操作都成功,整个事务才成功
代码中我们经常使用@Transactional注解来标记事务的原子性
2、一致性:
事务的一致性是指事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行前后,数据库都必须处于一致性状态。换句话说,事务的执行结果必须是使数据库从一个一致性状态转变到另一个一致性状态。
例子:
银行的转账操作就是一个事务。假设A和B原来账户都有100元。此时A转账给B50元,转账结束后,应该是A账户减去50元变成50元,B账户增加50元变成150元。A、B的账户总和还是200元。转账前后,数据库就是从一个一致性状态(A100元,B100元,A、B共200元)转变到另一个一致性状态(A50元,B150元,A、B共200元)。假设转账结束后只扣了A账户,没有增加B账户,这时数据库就处于不一致的状态。
3、隔离性:
事务的隔离性是指在并发环境中,并发的事务是相互隔离的,事务之间互不干扰。
MySQL中有分不同的事务隔离级别
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交 | 存在 | 存在 | 存在 |
读已提交 | 不存在 | 存在 | 存在 |
可重复读 | 不存在 | 不存在 | 存在 |
串行化 | 不存在 | 不存在 | 不存在 |
以上4个级别的隔离性依次增强,分别解决不同的问题。事务隔离级别越高,就越能保证数据的完整性和一致性,但同时对并发性能的影响也越大。
通常,对于绝大多数的应用来说,可以优先考虑将数据库系统的隔离级别设置为读已提交,这能够在避免脏读的同时保证较好的并发性能。尽管这种事务隔离级别会导致不可重复读、幻读和第二类丢失更新等并发问题,但较为科学的做法是在可能出现这类问题的个别场合中,由应用程序主动采用悲观锁或乐观锁来进行事务控制。
4、持久性:(redo 日志(前滚日志)实现)
事务的持久性又称为永久性,是指一个事务一旦提交,对数据库中对应数据的状态变更就应该是永久性的(被写入数据库中)。即使发生系统崩溃或机器宕机等故障,只要数据库能够重新启动,那么一定能够将其恢复到事务成功结束时的状态。