APP下载

通过程序案例讲解《数据库原理》课程中的并发控制

2018-12-21史胜利

现代计算机 2018年14期
关键词:事务语句代码

史胜利

(包头师范学院信息科学与技术学院,内蒙古 014030)

0 引言

并发控制是《数据库原理》课程的重要概念,并发控制技术涉及到多用户共享和事务处理技术,对于深入理解事务的特性、数据的共享、多用户并发操作都有重要的意义。同时并发控制教学对教师来说也是一个难点,并发操作带来的数据不一致性有多种情况,要理解这些不一致情况需要多方面知识,不仅仅涉及到一些SQL语句,还可能涉及到多用户访问、事务的隔离性和一致性等,往往需要一些具体的案例才能理解。

现有的《数据库原理》教材中都有并发控制的介绍,但内容上存在一些问题,例如都以理论讲解为主,使学生阅读起来困难;介绍的方法和概念很多,显得杂乱。这些问题可能在教师授课时也存在。教学中如果教师只讲理论,对于刚接触数据库的学生来说会有很大的难度,很难对并发操作出现的问题和并发控制方法留有深刻的印象。

1 程序案例

教师在讲解时可以使用程序案例把并发操作的整个过程都呈现出来,通过程序可以鲜活、生动的展示出现的问题,并很容易分析出产生问题的原因,既能引起学生的兴趣,又能使学生加深认识。下面给出一些讲解并发控制时的程序案例,代码是在MS SQL Server 2008中执行。

下面程序中用到的测试表Orders生成代码如下代码1:

CREATE TABLE Orders

(ID INT NOT NULL,Price FLOAT NOT NULL);

INSERT INTO Orders VALUES(10,10.00),(11,11.00),(12,12.00),(13,13.00),(14,14.00);

1.1 事务的原子性

事务是并发控制的基本单位,要理解并发控制首先要理解事务的原子性和事务处理命令。事务的原子性是事务中包括的诸操作要么都做,要么都不做。可以编写程序演示撤销事务部分操作的功能。下面的程序代码2演示事务的部分代码执行后出现错误,使用撤销语句恢复了数据。

begin

set xact_abort on;

begin try

begin tran

update orders set Price=Price+Price/10

where id=10;--执行成功

update orders set Price=Price+Price/0

where id=11;--除数为零错误,执行失败

commit tran

end try

begin catch

if xact_state()=-1--判断修改数据有没有出错

begin

rollbacktran;--事务执行中出错就撤销事务的所有操作

end

end catch

end

代码 2在 MS SQL Server 2008中执行,BEGIN TRAN、END TRAN、ROLLBACK TRAN语句分别用于标识事务开始、事务结束和撤销事务。上面的程序中事务的开始语句没问题,中间的操作会出现错误,这时使用回滚语句撤销了已执行的操作。

1.2 并发控制的必要性

并发控制讲解时需要让学生明白不实行并发控制会出现的问题。下面的程序代码3演示没有施行并发控制导致出现丢失更新问题。案例中使用两个用户同时连接数据库,然后两用户同时修改一个表中的数据时会引起丢失更新错误。

--第一步:用户A执行

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

Begin tran

Declare@n float=0

Select@n=price from orders where id=10

Set@n=@n-5

waitfor delay'00:00:30'

Update orders set price=@n where id=10;

Commit tran

--第二步:用户B执行

SET TRANSACTION ISOLATION LEVEL READ unCOMMIT⁃TED

Begin tran

Declare@n int;

Select@n=price from orders where id=10;

Set@n=@n-5;

Update orders set price=@n where id=10;Commit tran

按上面先后步骤执行时,用户A在修改操作之前有一个30秒的等待,所以用户B先修改数据,然后用户A后修改,用户A把用户B修改的数据覆盖掉了。

1.3 读脏数据

下面代码4演示出现读脏数据问题。下面代码中用户A读取被用户B修改但未提交的数据,而用户B在后续操作中又撤消了修改,这就会使用户A读取的数据成为脏数据。

--第一步:用户A中执行修改orders表数据

BEGIN TRANSACTION

UPDATE Orders SET Price=Price+1 WHERE ID=10

--第二步:用户B中执行读取orders表数据

SET TRANSACTION ISOLATION LEVEL READ UNCOMMIT⁃

TED

SELECT ID,Price FROM Orders WHERE ID=10;

--第三步:用户A中执行撤销修改操作

ROLLBACK TRANSACTION

按上面代码4先后步骤执行后,用户B中读到的数据就成为脏数据。

1.4 不可重复读

下面代码演示并发操作时出现不可重复读问题。下面代码5中用户A先读取了数据,之后数据被用户B修改,然后用户A重新读取数据时和先前读取的就不一致了。

--第一步:用户A中执行读取orders表数据

SET TRANSACTION ISOLATION LEVEL COMMITTED--(1)

BEGIN TRANSACTION

SELECT ID,Price FROM Orders WHERE ID=10

--第二步:用户B中执行修改orders表数据

UPDATE Orders SET Price=Price+1 WHERE ID=10

--第三步:用户A中执行读取orders表数据

SELECT ID,Price FROM Orders WHERE ID=10

COMMIT TRANSACTION

按照上面代码5的步骤执行后会出现不可重复读问题,如果把第一步中语句(1)中的“COMMITTED”换成“REPEATABLE READ”就可避免不可重复读的错误

1.5 幻读

下面代码6演示并发操作时出现的幻读问题。用户A先读取了表数据,之后用户B在表中插入了数据,然后用户A重新读取表时得到的数据比以前多了。

--第一步:用户A中执行读取orders表数据

SET TRANSACTION ISOLATION LEVEL COMMITTED--(2)

BEGIN TRANSACTION

SELECT ID,Price FROM Orders

--第二步:用户B中执行向orders表插入数据INSERT INTO Orders VALUES(15,15.00)

--第三步:用户A中执行读取orders表数据

SELECT ID,Price FROM Orders

COMMIT TRANSACTION

按照上面步骤操作会出现幻读问题。上面代码如果把第一步中(2)的“COMMITTED”修改为“SERIALIZ⁃ABLE”,可避免出现幻读问题。

1.6 死锁

下面代码7演示出现死锁问题。有table1和ta⁃ble2两个表,用户A先修改了table1的数据,这样就持有table1的更新锁,接着用户B修改了table2的数据,又试图修改table1,但用户A还没有释放table1的更新锁,然后用户A又试图修改table2,但用户B这时持有table2的更新锁,这样用户A和用户B都会因等待对方占有的资源而陷入长期的等待状态。

--步骤1:用户A执行锁定了资源1

Begin tran

Update table1 set col1=2

--步骤2:用户B执行锁定了资源2,试图锁资源1

Begin tran

Update table2 set col1=2

Update table1 set col1=2

--步骤3:用户A执行试图锁资源2,发生死锁

Update table2 set col1=2

2 结语

并发控制是《数据库原理》课程中的重要内容,通过一些程序演示可展示事务并发时出现的问题和并发处理过程,可以使学生加深对事务原子性、隔离性、一致性的认识,对并发操作会出现的读脏数据、不可重复读、幻读、丢失更新有一个具体直观的印象,使抽象的概念具体化,教学效果会好得多。

[1]王珊,萨师煊等.数据库系统概论(第5版)[M].北京:高等教育出版社,2014.9

[2]David M.Kroenke、David J.Auer著,朱居正译.数据库原理(第7版):使用Access 2013演示与实践[M].北京:清华大学出版社,2015.6.

[3]安博教育集团.Oracle数据库系统[M].北京:电子工业出版社,2012.2.

[4]孟宪虎,马雪英等.大型数据库管理系统技术应用与实例分析—SQL Server 2005(第二版)[M].北京:电子工业出版社,2011.5.

猜你喜欢

事务语句代码
北京市公共机构节能宣传周活动“云”彩纷呈北京市机关事务管理局
基于改进乐观两阶段锁的移动事务处理模型
一种Web服务组合一致性验证方法研究
Hibernate框架持久化应用及原理探析
神秘的代码
一周机构净增(减)仓股前20名
一行代码玩完19亿元卫星
近期连续上涨7天以上的股
我喜欢
冠词缺失与中介语句法损伤研究