详谈数据库事务

来源:互联网 发布:淘宝客网站推广技巧 编辑:程序博客网 时间:2024/06/03 21:02
一:事务的概念

事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。

二:事务的特性

事务有四个特性:ACID
原子性(atomicity):一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
隔离性(isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

事务实际上就是三个操作
begin tran
commit
rollback

三:事务的隔离级别

事务的隔离级别也有四个,分别为:读未提交(Read uncommitted),读已提交(Read committed),重复读(Repeatable read),序列化(serializable),而这四个级别也分别解决了脏读,不可重复读,幻读的问题。

3.1:读未提交

一个简单的case:用户A给B转账1000元,但是这个事务单元没有commit,B用户此时查询账户的确多了1000元,便安心没有在意这件事。然,A后续可能觉得转账转多了,实际上给转了500元,或者A直接rollback,则B得到的就是脏数据,即脏读。
小结:脏读发生在两个事务中,一个事务读取了另一个事务未提交的数据,如果另一事务修改了或者rollback了,第一个事务读取的就是脏数据。

3.2:读提交

一个简单的case:用户A去消费,查询账户还有1000元,然后用户B取出了A的1000元,并且事务已经commit。当A消费时,发现账户下没有钱。这就是不可重复读问题。
小结:读提交的隔离级别解决了脏读的问题;不可重复读发生在一个事务执行相同的查询两次或两次以上,但是每次都得到不同的数据;大多数数据库的默认级别就是Read committed,比如Sql Server , Oracle。

3.3:重复读
小个简单的case:用户A去打印了最近的800元消费流水,这个过程中B用户又消费了A账户的200元,A一看流水和账户余额,觉得不可思议,感觉发生了幻觉。这就是幻读的问题。
小结:重复读的隔离级别解决了不可重复读的问题;一个事务读取了几行数据,接着另一个并发事务插入了一些数据,在随后的查询中,第一个事务就会多了一些原本不存在的记;MySQL的默认隔离级别就是Repeatable read。

3.4:序列化
Serializable是最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻读。

四:事务调优:
在不影响业务的基础上
4.1:减少锁的覆盖范围
4.1.1.MyIsam 表锁-》Innodb行级锁
4.1.2.原味锁 (排他锁,读写锁)-》MVCC(Multi-Version Concurrency Control )多版本控制

4.2:增加锁上可并行的线程数
4.2.1.读写锁分离,允许并行读取数据

4.3:选择正确的锁类型
4.3.1.悲观锁:适合并发争抢比较严重的场景
OS中,请求资源,资源被锁,线程切换上下文出去,进入等待队列,锁释放,notify All,让之前请求的线程进入等待。(被动通知)
4.3.2.乐观锁:适合并发争抢不太严重的场景.
OS中,请求资源,资源被锁,线程不切换,一直循环等待,直到锁释放。(自动循环询问)









6 0
原创粉丝点击