事务上一系列SQL语句组成,用来保证要么一组全部完成,或者都不完成。事务执行中也支持回滚,保证操作中的任何数据修改都不会提交。事务里的操作其实是会立即在数据发生修改的,只是修改的数据不会被其他客户端的查询看见,因为用到了锁机制。
事务通常以BEGIN TRANSCATION开始,事务通常可以包含修改性的语句:insert、update、delete、merge(也就是select for update)。然后最终要么COMMIT或者ROLLBACK。除了显示表达commit或者roolback,还有隐形发生的roolback或者commit。比如
通常来说insert/update/delete/merge都包含子查询select语句。查询语句在事务内部看到是当前事务insert/update/delete/merge的最新数据,而在事务外面看不到这些数据更新,除非当前事务被commit之后。
事务最经常解决的是不同客户端的数据竞争问题。还可以用来,
SELECT columns FROM LiveTable
<Do calculations - 可以是SQL或者呼叫其他应用>
BEGIN TRAN
INSERT data INTO DataWarehous
UPDATE LiveTable SET ETLDone = 1 WHERE it was inserted into DW
COMMIT
不同的事务隔离机制提供了不同一致性等级。我们以云上存储系统为例。云存储在多个机器提供了冗余数据以面对不可预知的故障。数据在多台机器之间并不总是保持完全一致。因此数据从不同服务器读到的可能是不同版本的数据。
云产商比如微软Azure提供的是强一致性服务。强一致性服务确保所有客户端总是看到最后一次提交的数据。强一致性还比如经常用于数据中心之间的同步。这些数据中心常常分不在不同地理位置不同大洲的机房。
也有很多云存储系统比如Amazon S3设计为弱一致性的服务。这样设计的理由是强一致性是成本代价很大。通过对一致性的妥协来换取可用性和更好的性能。这种系统里,客户端可能读到的是过时的数据,不一定是最新版本的数据。读取过期数据会发现在还来不及同步其他数据中心的数据之前。这种系统也称为最终一致性。
当然还有些厂商提供了不同的级别来给用户选择,比如Amazon DynamoDB同时提供了强一致性和最终一致性。
还有些厂商提供了一种介于强一致性和最终一致性的方案。比如说读取到不过期5分钟的数据提交。
折衷一致性的背后原理就是CAP准则。CAP理论就是系统必须容忍网络分区的存在,用户必须在Consistency和Availablablity的之间选择。
我们来看一下一般数据库怎么做到事务隔离。
事务隔离级别有四种,以下图为例,四种隔离级别的读数据状态会是不一样的:
事务 A: |---0---|---1---|---2---|---3---|---4---|
事务 B: |---5---|---6---|---7---|---8---|
查询操作:|读事务开始 <--- 不同的隔离级别在不同的时间点读到不同的状态-->|
事务 A: |---0---|---1---|---2---|---3---|---4---|
事务 B: |---5---|---6---|---7---|---8---|
查询操作: 无论是读事务或者写事务 都会得到排他锁,如果是对同一记录操作,事务A一旦先开始,事务B就不能操作,或者查询也不能操作。
不可重复读的重点是修改:
同样的条件 , 你读取过的数据 , 再次读取出来发现值不一样了
幻读的重点在于新增或者删除(导致记录数变化)
同样的条件 , 第 1 次和第 2 次读出来的记录数(强调的是记录数,而不是记录本身,因为读锁的锁粒度是记录自身,而不是整张表)不一样。
通过在写的时候加锁,可以解决脏读。
通过在读的时候加锁(或者MVCC提供旧的提交版本),可以解决不可重复读。
通过串行化,可以解决幻读。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
READ UNCOMMITABLE | 1 | 1 | 1 |
READ COMMITABLE | 0 | 1 | 1 |
REPEATABLE READ | 0 | 0 | 1 |
SERIAL | 0 | 0 | 0 |
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。