事务并发实践
关键字:
事务、事务的ACID特性、事务并发、人大金仓、KingbaseES
1.事务概念
(1)事务的定义
事务(Transaction)是并发控制的基本单位,所谓事务是一个操作序列,这些操作要么都做,要么都不做,是一个不可分的工作单位。
(2)事务的使用
begin表示事务的开启;
commit表示事务的提交操作,表示该事务的结束,此时将事务中处理的数据刷到物理数据库磁盘中;
rollback表示事务的回滚操作,表示事务的异常结束,此时将事务中已经执行的操作撤销回原来的状态。
(3)事务的产生
数据库中的数据是共享资源,因此数据库系统通常要支持多个用户或不同应用程序的访问,并且各个访问进程都是独立执行的,这样就有可能出现并发存取数据的现象,如果不采取一定措施会出现数据异常的情况。
DBMS系统必须对这种并发操作提供一种相应的处理机制,来保证访问彼此之间不受任何干扰,从而保证数据库的正确性不受到破坏,为了避免数据库的不一致性,这种处理机制称之为“并发控制”,其中事务就是为了保证数据的一致性而产生的一种概念和手段(事务不是唯一手段)。
为了保证数据库中的正确性和一致性,事务具有四个特征,称为事务的 ACID 特性:
(1)原子性(Atomicity)
事务中的所有操作要么全部成功,要么全部失败,不会出现执行一半的情况,把这种特性叫做原子性。原子性是事务最重要的特性,全部执行失败并不是不执行,而是通过逆操作rollback回滚数据。事务中的一组更新操作是原子的,不可分割的,这些操作视为一个整体。
(2)一致性(Consistency)
事务必须满足数据库的完整性约束,且事务执行前后的数据必须保持一种合法的状态,也就是事务总是从一个一致性状态到另一个一致性状态。
事务的一致性与完整性是密不可分的,如银行转账需要先从A扣款再转到B,这两个动作是一个整体,要么全部操作,要么都不执行。
(3)隔离性(Isolation)
多个事务并发执行时,事务之间相互隔离,一个事务在执行的时候不影响另一个事务。一个事务的操作必须在一个事务的commit之后才可以进行操作。多事务并发时,相当于串行执行事务(锁),顺序执行。
(4)持久性(Durability)
即持续性,指一个事务一旦提交事务执行成功之后,所有被修改的数据都会被永久的保存下来,因为数据已经刷到了物理磁盘。
3.单个事务实践
(1)建立连接
在Linux中建立一个数据库服务端,另外建立两个客户端连接。
(2)建一个表并插入两条数据
create table aa(id int,name varchar(20),money decimal(10,2));
模拟银行交易建立表aa,里面包含了id,姓名和金额。
insert into aa values(1,'赵微',2000);
insert into aa values(2,'王泽林',2000);
select * from aa;
插入以上两条数据,数据格式跟刚刚创建的表对应起来。
图3-1 建表并插入相关数据
(3)开启事务(begin)
开启begin之后,往表里面插入一条数据,然后查看插入的数据,再切换到另一个客户端连接处查询。在begin前端可以查询到插入的数据,在另一个前端查询没有新插入的数据。
insert into aa values(3,'刘恺泽',3000);
图3-2 事务中插入数据
(4)提交事务(commit)
在begin前端输入commit;指令后,再次查询aa中的数据,两个前端都能查询到新插入的数据了。
图3-3 提交事务
(5)事务回滚(rollback)
在begin之后,进行一系列插入删除等操作,然后利用rollback;指令进行回滚,撤销在本次事务中进行的所有操作,之后提交事务,回到begin之前的状态。
图3-4 事务回滚
(6)建立保存点,事务回滚到保存点(savepoint)。
begin开启一个新的事务,然后往里面插入一条数据提交后,设定一个保存点,然后接着再插入一条数据,此时利用回滚到保存点的操作,可以保存保存点前的操作,保存点后的操作将无效,结束事务需要commit;提交。
insert into aa values(4,'陈友明',3000);
savepoint save1;
insert into aa values(5,'hiahiahia',3000);
rollback to save1;
图3-5 回滚保存点
4.事务的并发问题
事务是并发操作的基本单位,保证事务ACID特性是事务处理的重要任务,而事务特性遭到破坏的一个直接原因就是多个事务对数据库的并发操作引起的。为了保证事务的隔离性和一致性,DBMS必须对事务进行合理正确的调度。
事务并发可能导致事务之间交织操作,可能会出现数据不一致的问题,这种问题就是“并发问题”。典型的并发问题有三种:丢失更新问题,不可重复读问题,脏读数据。
(1)丢失更新问题
在两个客户端设两个事务T1和T2,同时读入一个数据时,事务T2提交的
结果会破坏事务T1提交的结果,由此导致T1的修改被丢失了,这就是由于数
据库并发操作引起的数据一致性问题。
实践:
1)在两个数据库客户端进行同时开启事务
图4-1 同时开启事务
2)左边客户端进行数据修改操作,如将赵微账户扣款1000,右边客户端账户扣款500。可以由下图看到,当左边写入一个数据右边紧跟着也写一个数据后,右边处于等待状态,一旦左边进行commit;提交后,右边写入成功,此时是数据库内部的锁进行了保护,避免了右边数据更改导致左边的数据更改丢失的问题。
update aa set money=money-1000 where id=1;
图4-2 事务中同时操作一个数据
(2)不可重复读
两个事物T1和T2,T1读取数据后,T2对数据进行了更改,T1再读取数据发现两次读取的数据不一样,后面读取无法再现第一次的读取结果。
实践:
两边同时开启事务,同时读取一个数据,右边进行数据修改,左边在读取数据,发现数据不一样了。
图4-3 不可重复读取数据
(3)读脏数据
事务T1修改了某一数据并将数据写入了,事务T2页读取了这个数据,然后T1撤销了这个数据写入的操作,恢复成原来的数据了,结果导致T2读取到了一条脏数据。




