第3章:复习篇——第5-2节:数据库编程2

目录

五、事务

1.事务的定义

2.事务的特性(ACID)

3.事务并发执行的问题

4.事务的隔离性(隔离级别)

[5.定义事务的 T-SQL 语句](#5.定义事务的 T-SQL 语句)

(1)显式事务定义

(2)隐式事务定义

(3)自动提交事务

[6.事务管理的 T-SQL 语句](#6.事务管理的 T-SQL 语句)

(1)显式事务管理

[①SAVE TRANSACTION语句](#①SAVE TRANSACTION语句)

[②BEGIN TRY 与 BEGIN CATCH 语句](#②BEGIN TRY 与 BEGIN CATCH 语句)

(2)隐式事务管理

7.实战训练

(1)课题

(2)基于该需求的事务实现思路

[(3)参考 T-SQL 代码示例](#(3)参考 T-SQL 代码示例)

六、锁

1.锁的概念

2.锁的分类

3.定义锁的关键字及作用

[4.使用锁的 T-SQL 语句](#4.使用锁的 T-SQL 语句)

七、游标

1.游标的概念

2.游标的作用

3.游标的组成与声明

4.游标声明的语法格式


五、事务

1.事务的定义

事务(Transaction)是由一组 T-SQL 命令组成的集合,作为一个整体执行:要么成功执行所有语句并修改数据,要么执行失败并将数据恢复到事务开始前的状态。例如:借书登记需同时修改读者已借总数、添加借书信息,事务可避免中途中断导致的数据不一致。


2.事务的特性(ACID)

事务需遵循 4 个原则,即 ACID 特性:

  1. 原子性(Atomic):事务是不可分割的最小单元,要么全执行,要么全不执行。
  2. 一致性(Consistency):事务执行前后,数据的完整性约束(如主键、外键)保持一致。
  3. 隔离性(Isolation):多个事务并发执行时,彼此的操作相互隔离,互不干扰。
  4. 持久性(Durability):事务提交后,修改的数据会永久保存,不会因故障丢失。

3.事务并发执行的问题

数据库多线程并发执行事务时,会出现以下问题:

  • 脏读:一个事务读取到另一个未提交事务的更新数据。
  • 不可重复读:一个事务多次读取同一行数据,结果却不同(被其他事务修改)。
  • 幻读:一个事务读取某范围数据时,其他事务对该范围执行插入 / 删除,导致前后读取的行数不一致。

4.事务的隔离性(隔离级别)

不同隔离级别可解决不同的并发问题:

  1. 未提交读(READ UNCOMMITTED):允许读取未提交的事务数据,效率高,但会出现脏读、不可重复读、幻读。
  2. 已提交读(READ COMMITTED):仅读取已提交的事务数据,可避免脏读,但仍存在不可重复读、幻读。
  3. 可重复读(REPEATABLE READ):事务修改数据时,禁止其他事务操作该数据,可避免脏读、不可重复读,但仍存在幻读。
  4. 可序列化(SERIALIZABLE):事务串行执行,可避免所有并发问题,但效率极低。

注:√表示能解决此类问题,× 表示不能解决此类问题。


5.定义事务的 T-SQL 语句

(1)显式事务定义

显式定义事务的启动和结束,以BEGIN TRANSACTION开始,COMMIT TRANSACTION结束,可通过ROLLBACK TRANSACTION回滚。

  • BEGIN TRANSACTION 语句

    BEGIN { TRAN | TRANSACTION }
    [ {事务名 | @事务变量名 }
    [WITH MARK [description]]
    ]

WITH MARK [description]:在日志中标记事务,description为标记描述;使用该选项时必须指定事务名。

  • COMMIT TRANSACTION 语句:提交事务,永久保存事务执行结果:

    COMMIT { TRAN | TRANSACTION }
    {事务名 | [@事务变量名 ]}

  • ROLLBACK TRANSACTION 语句:回滚事务,将数据恢复到事务开始前的状态:

    ROLLBACK {TRAN|TRANSACTION}
    [ 事务名| @事务变量名 ]

(2)隐式事务定义

无明显事务标志,需通过SET IMPLICIT_TRANSACTION ON启动;启动后形成事务链,前一个事务完成后自动启动新事务,需用COMMIT/ROLLBACK提交 / 回滚。

SQL Server 中自动启动事务的语句:ALTERCREATEDELETEDROPFETCHGRANTINSERTOPENREVOKESELECTTRUNCATE TABLEUPDATE

执行SET IMPLICIT_TRANSACTIONS OFF可结束隐式事务模式。

(3)自动提交事务

SQL Server 默认模式,每条语句都是一个独立事务,执行后自动提交 / 回滚;未指定显式 / 隐式事务时,默认使用此模式。


6.事务管理的 T-SQL 语句

(1)显式事务管理

①SAVE TRANSACTION语句

SQL Server 提供SAVE TRANSACTION语句,用于在事务中创建保存点,可选择性回滚到指定保存点(无需回滚整个事务),减少时间开销。语法格式:

复制代码
SAVE { TRAN|TRANSACTION }
{ 保存点名 | @保存点变量}
②BEGIN TRY 与 BEGIN CATCH 语句

这是 SQL Server 2016 中用于捕获和处理事务异常的语句,可在事务管理中处理错误。语法格式:

复制代码
BEGIN TRY
    SQL 语句
END TRY
BEGIN CATCH
    捕获错误与处理异常的语句
END CATCH

(2)隐式事务管理

隐式事务通过SET IMPLICIT_TRANSACTIONS ON开启,开启后会自动启动事务并形成事务链 ;可通过COMMIT TRAN/ROLLBACK TRAN将事务链分割为多个事务,减少回滚开销。

可结合判断语句(通过@@ERROR判断是否出错)管理事务:

复制代码
--上一个事务
IF  @@ERROR!=0
    ROLLBACK TRAN
ELSE
    COMMIT TRAN
--下一个事务

7.实战训练

(1)课题

在学生选课管理数据库 SCC 中,利用事务进行学生选课管理,需要实现的功能为:在原有班级新增 1 名学生,选修 2 门课程,所选课程学分必须大于或等于 6 分,并录入学生成绩,得分规则为百分制,范围是 0~100 分。

(2)基于该需求的事务实现思路

要完成这个功能,可通过显式事务 结合BEGIN TRY/BEGIN CATCH处理异常,步骤如下:

  1. 开启事务,定义保存点(可选);
  2. 向学生表(如Student)插入新学生记录;
  3. 查询学分≥6 的课程,选择 2 门;
  4. 向选课成绩表(如Score)插入这 2 门课的成绩(确保成绩在 0~100 之间);
  5. 若所有操作无错误则提交事务,若有错误则回滚事务。

(3)参考 T-SQL 代码示例

复制代码
USE SCC
GO

BEGIN TRY
    -- 开启显式事务
    BEGIN TRANSACTION;

    -- 步骤1:新增学生(假设Student表字段:Sno学号、Sname姓名、Class班级等)
    INSERT INTO Student(Sno, Sname, Class, ...)
    VALUES('s032190125', '张三', '计科2301', ...); -- 填写实际字段值

    -- 步骤2:选择2门学分≥6的课程(假设Course表字段:Cno课程号、Credit学分)
    -- 先查询符合条件的课程(示例选c001、c002,实际可根据需求选择)
    DECLARE @Course1 CHAR(4), @Course2 CHAR(4);
    SELECT TOP 2 @Course1=Cno, @Course2=Cno 
    FROM Course 
    WHERE Credit >= 6; -- 确保选2门学分≥6的课

    -- 步骤3:录入这2门课的成绩(假设Score表字段:Sno、Cno、Uscore平时分、EndScore期末分等)
    -- 成绩确保在0~100之间
    INSERT INTO Score(Sno, Cno, Uscore, EndScore)
    VALUES('s032190125', @Course1, 85, 90), -- 平时分、期末分符合0~100
          ('s032190125', @Course2, 78, 88);

    -- 所有操作成功,提交事务
    COMMIT TRANSACTION;
    PRINT '事务执行成功:新增学生及选课成绩完成';
END TRY
BEGIN CATCH
    -- 捕获错误,回滚事务
    ROLLBACK TRANSACTION;
    PRINT '事务执行失败:' + ERROR_MESSAGE(); -- 输出错误信息
END CATCH
GO



六、锁

1.锁的概念

锁是用于控制数据库并发操作的机制,SQL Server 通过锁防止多用户操作同一数据导致的数据不一致问题。其作用是:确保事务完整性与数据库一致性,防止用户读取其他用户正在修改的数据,避免多用户同时修改相同数据;若不使用锁,数据可能逻辑错误,查询结果会异常。


2.锁的分类

SQL Server 中常用锁的类型:

  • 共享锁(读锁):添加后,其他用户无法修改加锁数据,但可读取。
  • 排他锁(独占锁):添加后,其他事务无法访问、修改加锁数据。
  • 更新锁:用于防止死锁,一个事务最多只能获取一个更新锁权限。
  • 意向锁:位于锁层次结构的底层资源,在低级锁锁定资源前提供意向标识。
  • 架构锁:表修改、存储过程重编译时添加,例如修改 / 删除视图、存储过程、表等。
  • 大容量更新锁 :向表大容量复制数据时,通过TABLOCK提示使用。
  • 键范围锁:事务使用可序列化隔离级别时使用的锁。

3.定义锁的关键字及作用


4.使用锁的 T-SQL 语句

  • 对某一行添加锁

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
    SELECT * FROM 表名 ROWLOCK WHERE id = 666

说明:设置事务隔离级别为 "未提交读",查询时对id=666的行添加共享锁。

  • 锁定数据库的一个表

    SELECT * FROM 表名 WITH (HOLDLOCK)

说明:对表添加 "保持锁",事务结束前不会释放该表的共享锁。




七、游标

1.游标的概念

游标是 SQL Server 的一种数据访问机制,允许用户访问单独的数据行,对每行数据单独处理,降低系统开销;也可利用数据生成 SQL 代码并立即执行 / 输出。

游标主要用于存储过程、触发器和 T-SQL 脚本中,类似 C 语言的指针,可在结果集中前后浏览数据,指向任意位置;对结果集逐行处理时,需声明指向该结果集的游标变量。


2.游标的作用

  • 从多条数据的结果集中每次提取一条记录。
  • 与 SQL 查询语句关联,由结果集和游标位置(指向特定记录的指针)组成。
  • 允许对 SELECT 结果集中的每行执行相同 / 不同操作。
  • 支持基于游标位置对表中行进行删除和更新。

3.游标的组成与声明

游标由游标结果集 (定义游标的 SELECT 语句返回的行集合)和游标位置(指向结果集某一行的指针)组成。

游标不是数据库对象,需通过DECLARE CURSOR语句声明(类似变量声明),声明时关联 SELECT 语句但不执行。


4.游标声明的语法格式

复制代码
DECLARE 游标名 CURSOR[LOCAL|GLOBAL]
[FORWARD_ONLY|SCROLL]
[STATIC|KEYSET|DYNAMIC|FAST_FORWARD]
[READ_ONLY|SCROLL_LOCKS|OPTIMISTIC]
[TYPE_WARNING]
FOR SELECT 语句
[FOR UPDATE [OF column_name [,...n]]]

语法参数说明

  1. LOCAL/GLOBAL:游标作用域,LOCAL 为局部,GLOBAL 为全局。
  2. FORWARD_ONLY/SCROLL:游标移动方向。
  3. STATIC|KEYSET|DYNAMIC|FAST_FORWARD:游标类型定义。
  4. READ_ONLY|SCROLL_LOCKS|OPTIMISTIC:游标或基表的访问属性。
  5. TYPE_WARNING:游标类型隐式转换时,向客户端发送警告。
  6. FOR UPDATE :指定游标中可更新的列;带OF column_name则仅能修改指定列,否则可修改所有列。
相关推荐
islandzzzz2 小时前
SQL学习应用工作场景(2)--执行优先级+语法顺序+保留2位小数
数据库·sql·学习
代码游侠2 小时前
学习笔记——数据封包拆包与协议
linux·运维·开发语言·网络·笔记·学习
开开心心_Every2 小时前
定时管理进程:防止沉迷电脑的软件推荐
xml·java·运维·服务器·网络·数据库·excel
hopsky2 小时前
SQL语义校验方案
数据库·oracle
几度风雨见丹心2 小时前
uniapp项目使用sqlite数据库
数据库·sqlite·uni-app
航Hang*2 小时前
第3章:复习篇——第5-1节:数据库编程1
数据库·笔记·sql·mysql·sqlserver
Mr.朱鹏2 小时前
分布式接口幂等性实战指南【完整版】
java·spring boot·分布式·sql·spring·云原生·幂等
一个天蝎座 白勺 程序猿2 小时前
破局困境:Oracle迁移金仓KingbaseES数据库的深度实践
数据库·sql·oracle·kingbase·kingbasees·金仓数据库
航Hang*2 小时前
第3章:复习篇——第6节:数据库安全管理与日常维护
数据库·笔记·sql·mysql