事务的四大特性
四大特性为:原子性,一致性,隔离性,持久性 ACID
1,原子性(Atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败,则不能对数据库有任何影响
2,一致性(Consistency)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态。也就是说一个事务执行之前和执行之后都必须处于一致性状态。举个例子,假如A和B两个人总共100块钱。那么不管A和B之间怎么进行转账,最终的结果两个人加起来也是100元
3,隔离性(lsolation)
隔离性是当多个用户并发访问数据库时,比如同时操作一张表,数据库为每个用户开启一个事务,不能被其他事务的操作所干扰。多个并发事务之间要相互隔离。关于事务的隔离性数据库提供了多种隔离级别。
4,持久性(Durability)
持久性是指一个事务一单被提交,那么对数据的影响将是永久的,即使在数据库系统遇到古装的情况下也不会丢失提交的操作。
事务的隔离级别
1,为什么要设置隔离级别
在数据库操作中,在并发的情况下,可能出现一些问题
更新丢失
如果多个线程操作,基于同一个查询结构对表中的记录进行修改。那么后修改的记录将会覆盖前面修改的记录,前面修改的就丢失了。这就叫更新丢失。这是因为心痛没有执行任何锁操作。因此并发事务并没有隔离开来。
第一类丢失更新:事务A撤销时,把已经提交的事务B的更新数据覆盖了
第二类丢失更新:事务A覆盖了事务B已经提交的数据,造成事务B所做的操作丢失(解决办法,对行加锁,只允许并发一个更新事务)
脏读(dirty Reads)
脏读:事务A 读取事务B尚未提交的数据并在此基础上操作,而事务B执行回滚,那么事务A读取到的数据就是脏数据
解决办法:如果在第一个事务提交前,任何其他事务不可读取其修改过的值,则可避免该问题
不可重复读(non-repeatable Reads)
一个事务对同一行数据重复读取两次,但是却得到的结果不一致。事务A读取某一数据后,事务B对其做了修改,当事务A再次读取时候,发现和第一次读取的不一致。
解决办法:如果在修改事务提交后,才可以读取就可以避免此问题。
幻读:指两次执行同一条select语句会出现不同的结果,第二次读会增加一数据行,并没有说两次执行是在同一个事务。一般情况下,幻读应该正视我们所需要的,但是有时候却不是。如果打开的游标,在对游标进行操作时,并不希望新增的记录加到游标命中的数据库中,隔离级别为:游标稳定性的。可以阻止幻读。
解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,就可以避免。
2,事务的隔离级别
Read uncommitted (读未提交)
如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作。但是允许其他的事务读此行数据。该隔离级别可以通过 “排它写锁” 实现。但是这样就会出现脏读的情况。
Read commited (读已提交)
读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。该隔离级别避免了脏读,但是却可能出现不可重复读。
Repeatable read (可重复读)
可重复读是指在一个事务内,多次读同一数据,在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,即使第二个事务对数据进行修改,第一个事务两次读取到的数据也是一致的。这就是可重复读。读取数据的事务会禁止写事务(但允许读),写事务则禁止任何其他事务。这样避免了不可重复读和脏读,但是有时可能出现幻读。,这个可以通过共享锁和排它写锁实现。
串行化
提供严格的事务隔离级别,他要求事务序列化执行,事务只能一个接着一个的执行。但不能并发执行。如果仅仅通过 “行级锁” 是无限实现事务序列化的。必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务所查到。