一般来说,事务对应一个完整的业务(例如银行账户转账业务),事务反映在数据库中就是用户一系列的数据库操作。一个完整的业务需要批量的DML(insert、update、delete)语句共同完成,事务保证这些操作要么全做要么全不做,是一个不可再分的工作单元。
事务的 ACID 原则保证了一个事务要么成功提交,要么失败回滚,二者必居其一。它对数据的修改具有可恢复性。即当事务失败时,它对数据的修改都会恢复到该事务执行前的状态。具体ACID是什么意思呢:
Atomicity:原子性
事务必须是原子单元,最小单元,不可再分。事务中的操作要么全都执行,要么全都不执行,不能只完成部分操作。原子性在数据库系统中,由恢复机制来实现。
Consistency:一致性
事务操作前后,数据库总是由一个一致性状态到另一个一致性状态。数据库一致性的定义是由用户负责的。例如,在银行转账中,用户可以定义转账前后两个账户金额之和保持不变。
Isolation:隔离性
隔离性说的是不同事务之间是互相隔离的。系统必须保证事务不受其他并发事务的影响。当多个事务同时运行时,各事务之间相互隔离。事务查看数据时所处的状态,要么是另一个并发事务修改它之前的状态,要么是另一个并发事务修改它之后的状态,事务能查看中间状态的数据。隔离性通过系统的并发控制机制实现。
Durability:持久性
事务完成后对数据所做的任何变动在系统中是永久有效的,即使该事务产生的修改不正确,错误也将一直保持。(内存数据持久保存到磁盘文件中)持久性通过恢复机制实现,发生故障时,可以通过日志等手段恢复数据库信息。
1.开启事务 start transaction;
开启之后,下面紧跟的的sql语句并不会马上执行并把结果写到表中,而是会写到事务日志中
结束事务时可以通过提交或回滚结束,分别表示事务成功或失败
2.事务提交 commit;
将sql语句的结果写到数据表中
3.事务回滚 rollback;
回滚会清掉开始事务管理之后写到事务日志中的内容,即恢复到开启事务管理之前
所以看到这里知道为什么事务可以保证一致性了吗?
事务失败会导致事务回滚,不会提交,此时数据还根本没有写到数据库表里。另外,事务一旦成功提交,便不能再回滚,若要回滚必须发生在提交之前。
不同事务之间具有隔离性,事务的隔离级别共分4种:
事务的隔离级别 1未提交读:read uncommitted
2已提交读:read committed3可重读:repeatable read4串行化:serializable
1.未提交读 --- 脏读
例如并发执行两个事务A和B,事务B在事务A还未提交数据时就可以读取到数据。这种现象就叫做未提交读,也叫“脏读”,读取到的数据叫做“脏数据” 。这种操作安全性最低,隔离级别最低。数据库隔离级别一般都高于该级别,不会出现这样低级别的隔离性。
风险:脏读。事务B读到了事务A正在处理的数据,这是完全没有准确性保证的数据,可能下一时刻数据就又变了。
2.已提交读 --- 不可重读
并发执行两个事务A和B,事务B要等到事务A提交之后才能读取数据,这种现象就叫做已提交读。这种隔离级别高于未提交读。这种级别可以避免"脏读",但是这种隔离级别会导致“不可重读”
Oracle数据库默认隔离级别就是已提交读
风险:不可重读。不可重读的意思这么理解比较好,就是说如果重读,会出问题。举个例子,事务B在事务A开始之前读了某部分数据,在事务A提交之后,又读了这一部分数据,但是这部分数据刚才被事务A改动了。所以出现了前后两次读取(第二次相当于重读一次)数据不一致的情况。
3.可重读 --- 幻读
并发执行两个事务A和B,无轮在谁先开启事务,数据将不允许再被修改(update),这种现象叫做可重读。这种隔离级别高于已提交读。 这种隔离级别可以避免“不可重读”现象,但是会导致“幻读” MySQL数据库默认此隔离级别
风险:幻读。幻读其实也是指两次读到的数据不一致,好像出现了幻觉。幻读和不可重读的差别在于,幻读针对的不是update操作,而是insert操作。例如事务A和事务B并发执行,此时事务A查了部分数据,之后事务B不能进行update操作,但是进行了insert操作,所以数据中关于总数之类的数据会增加,事务B提交之后,事务A再查,发现有一部分数据又不一样了,这就是幻读。
4.串行化
串行化也叫序列化。是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种隔离级别效率太低,比较耗数据库性能,一般不使用。
大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。Mysql的默认隔离级别是Repeatable read。
事务日志的用途一般是用来备份和恢复数据的。
可以帮助提高事务的效率。
事务的每一个操作都会先写入到事务日志文件中,此时写入的仅仅是操作过程,并不是操作的大量数据,并且日志的操作是磁盘上的一小块顺序IO,速度很快。写入日志文件后,再进行数据库文件的操作,将已提交的事务数据写入到数据库文件。在事务期间如果系统崩溃,存储引擎在重启时可以依靠事务日志自动恢复出错的数据。
以上!