关于MYSQL中的事务
mysql中只有innodb支持事务。
事务有4个特点
1、原子性(Atomicity)
事务中包含的程序作为数据库的逻辑工作单位,它对数据库中的数据进行操作时,要么全部执行,要么都不执行。
举个例子,你给小A转账500块时。这个时候银行的数据库会将你卡里的金额减500,同时小A卡里的金额增加500。不存在你的钱被扣,小A的钱没加。或者你的钱没扣,小A的钱增加了。
2、一致性(Consistancy)
一个事务执行前和执行后,数据库都必须要处于一致性的状态。
这句话是怎么理解:就是你给小A的卡里转了500块,不管怎么样你卡里的钱和小A卡里的钱的总和是不变的。不会出现你们两的钱相加之和会出现变化的。
3、分离性、独立性(Isolation)
分离性是指在并发的事务是相互隔离的。即一个事务的内部操作及正在操作的数据必须被封锁起来,不会被其他的事务来企图修改。这一点和Java中多线程编程的同步锁很像。
举个例子:假如你给小A打钱过去,同时小B也在给小A打钱。这时候数据库服务器中要么会让你的事务先执行,或者让小B的事务先执行。不存在你两个的打钱动作会同时来修改小A卡里的金额。
4、持久性(Durability)
持久性是指当数据库系统出现故障了,要确保已经提交的事务的更新是不会丢失的。即数据库中的数据的修改是永久性的。就算系统出现了故障,我们也可以使用数据库的备份和恢复来保证数据的修改。
举个例子:当你从卡里面取出500块,在银行的数据库中你的卡里的金额会减少500。就算银行的数据库进行维修,等到再次恢复的时候你的卡里的钱还是减少500的。不存在取了钱,由于数据库的故障你卡里的钱不变这种情况。
这可能是我看到过的最逼真的解释了。
由于事务的影响,并发会造成一些副总用:
- 更新丢失(Lost Update):(我的修改被别人覆盖)
当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题——最后的更新覆盖了其他事务所做的更新。例如,两个编辑人员制作了同一文档的电子副本。每个编辑人员独立地更改其副本,然后保存更改后的副本,这样就覆盖了原始文档。最后保存其更改保存其更改副本的编辑人员覆盖另一个编辑人员所做的修改。如果在一个编辑人员完成并提交事务之前,另一个编辑人员不能访问同一文件,则可避免此问题。
- 脏读(Dirty Reads):(我读到的数据已经被人修改)
一个事务正在对一条记录做修改,在这个事务并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”的数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象地叫做“脏读”。读取到的数据不真实。
- 不可重复读(Non-Repeatable Reads):(我读到的数据已经被人修改)
一个事务在读取某些数据已经发生了改变、或某些记录已经被删除了!这种现象叫做“不可重复读”。
- 幻读(Phantom Reads):(我读到的数据已经被人修改)
一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。
更新丢失是对数据的操作造成的。
这种情况需要通过程序的方式去避免。例如:加乐观锁等。
脏读/不可重复读/幻读
这三种都是读一致性的问题。可以通过数据库的设置来解决。
mysql支持4种事务隔离级别。这是一个标准。
隔离级别/读数据一致性及允许的并发副作用 读数据一致性 脏读 不可重复读 幻读
未提交读(Read uncommitted) 最低级别,只能保证不读取物理上损坏的数据 是 是 是
已提交度(Read committed) 语句级 否 是 是
可重复读(Repeatable read) 事务级 否 否 是
可序列化(Serializable) 最高级别,事务级 否 否 否
可以通过以下语句获取mysql默认的事务隔离级别。
select @@tx_isolation;
+-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+