MSSQL-并发控制-1-Transaction
1 事务类别
1.1 显式事务
1.1.1 COMMIT
begin tran yu1
select @@TRANCOUNT
begin tran yu2
insert into tbxin(name,age) select '第2层tran',100;
select @@TRANCOUNT begin tran yu3
insert into tbxin(name,age) select '第3层tran',100;
select @@TRANCOUNT
commit tran --等同于 commit tran anyname
select @@TRANCOUNT
commit tran --等同于 commit tran anyname
select @@TRANCOUNT
commit tran --等同于 commit tran anyname
select @@TRANCOUNT
1.1.2 ROLLBACK
- 第一个,回滚当前所有未结束事务
- rollback = rollback tran = rollback transaction = rollback work
- 无论嵌套了多少事务,@@trancount为多少,执行 rollback则直接回滚所有嵌套事务,设置@@trancount为0
- 常见错误案例:EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 1,当前计数 = 0。
- 第二个,回滚到某个保存点的位置
- rollback tran savepoint_name
- 不影响@@trancount计算,回滚到 某个 save tran savepoint_name的位置
CREATE PROC p_count
AS
begin transaction
insert into tbxin(name,age) select '第一层tran',200;
rollback transaction
GO BEGIN TRAN
EXEC p_count
select @@TRANCOUNT 消息 266,级别 16,状态 2,过程 p_count,第 0 行
13 EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 1,当前计数 = 0。
1.1.3 SAVE TRANSACTION
- save transaction [savepoint_name] 提供 用户 在事务内设置保存点或标记,所以 save transaction 只能在事务内部执行;
- save transaction [savepoint_nmae] 不影响 @@trancount 计数;
- 注意 save transaction [savepoint_name] 只有对应 rollback transaction [savepoint_name],并没有对应 commit transaction [savepoint_name],强调下:对应的rollback transaction [savepoint_name] 是有带 保存点名字的,如果没有带名字,则会回滚整个最外部的事务;
- save transaction 对应的 rollback transaction [savepoint_name]并不需要一一对应,可以多个save tran 对应0到多个rollback tran;
- 事务内,可以有多个 save transaction [savepoint_name],可使用 rollback transaction [savepoint_name] 回滚到任意一个保存点;
- 支持savepoint_name重复命名,但是不建议。在事务中允许有重复的保存点名称,但指定保存点名称的 ROLLBACK TRANSACTION savepoint_name 语句只将事务回滚到使用该名称的最近的 SAVE TRANSACTION savepoint_name;
- 在使用 BEGIN DISTRIBUTED TRANSACTION 显式启动或从本地事务升级的分布式事务中,不支持 SAVE TRANSACTION。
begin tran
select @@TRANCOUNT save tran yu1
insert into tbxin(name,age) select '第1层save',100;
select @@TRANCOUNT save tran yu2
insert into tbxin(name,age) select '第2层save',100;
select @@TRANCOUNT save tran yu3
insert into tbxin(name,age) select '第3层save',100;
select @@TRANCOUNT save tran yu4
insert into tbxin(name,age) select '第4层save',100;
select @@TRANCOUNT rollback tran yu3
select @@TRANCOUNT commit tran yu2
select @@TRANCOUNT rollback tran
1.1.4 XACT_ABORT

1.2 隐式事务
- ALTER TABLE
- CREATE
- DROP
- OPEN
- FETCH
- GRANT
- REVOKE
- SELECT
- UPDATE
- DELETE
- INSERT
- TRUNCATE TABLE
1.3 自动提交事务
--例子
INSERT INTO ...
--数据库默认的事务管理模式,在没有被显式事务及隐式事务覆盖的情况下,自动在每个Tsql完成时,提交或者回滚
1.4 手动提交事务
--例子
BEGIN TRAN
INSERT INTO ...
COMMIT / ROLLBACK
--数据库默认的事务管理模式,显式事务在完成时,手动指定SQL,说明提交或者回滚。
1.5 批范围事务
1.6 分布式事务
BEGIN DISTRIBUTED TRANSACTION
SELECT ... FROM Stock... WHERE ...
UPDATE Stock ...
INSERT INTO ORDERS ...
COMMIT
在SQL SERVER中,如果没有配置服务器的DTC服务,使用分布式事务的时候,会报错如下:
(1 行受影响)
消息 8501,级别 16,状态 3,第 4 行
服务器 'XINYSU\MSSQL' 上的 MSDTC 不可用。
(1 行受影响)
链接服务器"test_xinysu"的 OLE DB 访问接口 "SQLNCLI11" 返回了消息 "该伙伴事务管理器已经禁止了它对远程/网络事务的支持。"。
消息 7391,级别 16,状态 2,第 4 行
无法执行该操作,因为链接服务器 "test_xinysu" 的 OLE DB 访问接口 "SQLNCLI11" 无法启动分布式事务。
如果实例需要支持分布式事务,则需要在双方的服务器其上开启DTC服务,运行XA事务。这里注意一点,如果链接服务器是MySQL数据库,因为mysql的odbc不支持 XA事务,所以,会报错 无法启动分布式事务。官网解释如下:


INSERT INTO mssql_xinysu.dbname.dbo.tbid(id) select id from sys.sysobjects
或者
INSERT INTO openquery([mysql_xinysu],'select id from tbid') select id from sys.sysobjects
假设 select id from sys.sysobjects 的结果有2k行,则在 第一个SQL的 ODBC 是这么处理的:
- 分为2000个INSERT 语句
- (@Param000004 int)INSERT [dbname].[dbo].[tbid]([id]) VALUES(@Param000004)
- 一条一条INSERT
- 分为2000个INSERT 语句
- INSERT INTO tbid ([id]) VALUES(单个的ID值)
- 一条条INSERT
2 ACID特性
2.1 Atomicity

2.2 Consistency
2.3 Isolation
2.4 Durability
3 协议
3.1 2PL
BEGIN
LOCK A
READ A
A:A+100
WRITE A
UNLOCK A
LOCK B
READ B
UNLOCK B
COMMIT
两阶段锁还有几种特殊情况:conservative(保守)、strict(严格)、strong strict(强严格),这三种类型在加锁和释放锁的处理有些不一样。
- conservative
- 在事务开始的时候,获取需要的记录的锁,避免在操作期间逐个申请锁可能造成的锁等待,conservative 2PL 可以避免死锁
- strict
- 仅在事务结束的时候(commit or rollback),才释放所有 write lock,read lock 则正常释放
- strong strict
- 仅在事务结束的时候(commit or rollback),才释放所有锁,包括write lock 跟 read lock 都是结束后才释放。
3.2 XA
3.2.1 CAP理论
- Consitency
- 一致性,在分布式存储系统中,对于每一次的读操作,对于读到的数据,要么都是最新的,要么则返回一个错误
- 这里的CAP的C跟ACID的C虽然是一个单词,但是含义不一样哦,记得区分
- 在关系型数据库里边,通常优先考虑到是一致性
- Availability
- 可用性,保证每次请求都正常,但不要求返回的结果是最新的数据
- Partition tolerance
- 分区容错性,当各个分区之间因为网络发生消息丢失或者延迟是,分布式存储系统仍能正常运行。
- 则是在操作 涉及多个服务器的事务 过程中,
3.2.2 2PC

- Prepare
- 事务协调器coordinator 对 涉及到的节点 发起 操作申请;
- 各个节点获取到 操作后,直接在 数据库中执行,并存放相关的日志到redo / undo log中,注意注意,这里仅是操作,并没有提交或者回滚该操作;
- 各节点将处理日志写入磁盘;
- 返回信息给coordinnator
- 如果节点可以正常执行,则返回 Ready 通知 coordinator;
- 如果节点不可以正常执行,则该节点本地回滚该操作,并返回 Not Ready 通知 coordinator
- Comiit/Rollback
- coordinator 根据各个节点 的反馈信息,来决定 该事务操作的结果
- coordinator将 操作结果记录到日志中
- 反馈操作结果给各个节点
- 如果出现一个或者一个以上的节点 反馈回来 Not Ready的通知,则coordinator会通知 正常执行操作的节点 回滚事务
- 如果没有出现 Not Ready 的反馈,则coordinator会通知所有节点 COMMIT 操作。
- 事务协调器宕机
- 这里需要引入一个新角色:coordinator watchdog,事务协调器看门狗
- 无论是coordinator 还是分布式系统的各个节点,在操作过程中,都会记录当前操作的状态日志。当出现异常或者恢复时,可以通过日志来判断当前的情况。
- 当 coordinator 发起提议后宕机,而此时各个节点开始操作,然后反馈给 coordinator,但是 迟迟没有接收到 coordinator 的回应,那么各个节点的操作就无法回滚或者提交,处于堵塞情况。而 coordinator watchdog 则可以解决这个堵塞现象,当coordinator宕机一定时间后,看门狗会自动 担任 coordinator 的工作,接收各个节点的 反馈情况,然后再根据反馈结果传递 COMMIT/ROLLBAK给各个节点。
- 节点宕机
- prepare阶段宕机,则coordinator接收到事务后发送给各个节点需要做的 操作时,节点发生宕机,这个时候,则该节点无法返回 Ready 的消息,coordinator则默认接受该节点发出的 abort 信息,coordinator通知其他各个节点 Rollback 操作;
- Comiit/Rollback阶段宕机,由于各个节点及coordinator都有日志记录,coordinator会记录这个事务是会提交还是回滚,当 节点宕机后,其他节点根据coordinator的通知执行ROLLBACK或者COMMIT,而宕机节点本地会记录该事务操作未执行提交或者回滚,节点恢复后,会从 coordinator 日志中读取日志,重新处理该操作。
3.2.3 XA协议
MSSQL-并发控制-1-Transaction的更多相关文章
- 并发控制MsSql
Isolation 阅读目录(Content) 1 并发控制理论 1.1 悲观并发控制 1.2 乐观并发控制 2 隔离级别 2.1 隔离级别说明 2.2 Read Commmitted Snaps ...
- MSSQL Server Transaction 数据库事务回滚的用法
使用的表结构如下: Commit TransAction Else Rollback TransAction/* 自定义一个变量来判断最后是否发生过错误.*/ ...
- MSSQL Transaction[事务] and Procedure[存储过程]
--事务分三种 --1.显示事务 --我们手动begin transaction ...... commit transaction/rollback transaction --上面这种写法叫做“显 ...
- MSSQL事务隔离级别详解(SET TRANSACTION ISOLATION LEVEL)
控制到 Transact-SQL 的连接发出的 SQL Server 语句的锁定行为和行版本控制行为. TRANSACT-SQL 语法约定 语法 -- Syntax for SQL Server ...
- 浅谈MS-SQL锁机制
锁的概述 一. 为什么要引入锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 丢失更新A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系统 脏 ...
- 再谈Transaction——MySQL事务处理分析
MySQL 事务基础概念/Definition of Transaction 事务(Transaction)是访问和更新数据库的程序执行单元;事务中可能包含一个或多个 sql 语句,这些语句要么都执行 ...
- 分享MSSQL、MySql、Oracle的大数据批量导入方法及编程手法细节
1:MSSQL SQL语法篇: BULK INSERT [ database_name . [ schema_name ] . | schema_name . ] [ table_name | vie ...
- EntityFramework与TransactionScope事务和并发控制
最近在园子里看到一篇关于TransactionScope的文章,发现事务和并发控制是新接触Entity Framework和Transaction Scope的园友们不易理解的问题,遂组织此文跟大家共 ...
- LINQ to SQL语句(13)之开放式并发控制和事务
Simultaneous Changes开放式并发控制 下表介绍 LINQ to SQL 文档中涉及开放式并发的术语: 术语 说明 并发 两个或更多用户同时尝试更新同一数据库行的情形. 并发冲突 两个 ...
随机推荐
- Java面向对象 String 基本数据类型对象包装类
Java面向对象 String 知识概要: (1)String的用法详解 (2)基本数据类型对象包装类 String 顾名思义,该类主要是对字符串 ...
- SerialPort如何读取串口数据并显示在TextBox上,多线程委托
namespace SerialPort { public partial class Form3 : Form { delegate void UpdateTextEventHandler(stri ...
- linux上redis安装配置及其防漏洞配置及其攻击方法
Linux上redis安装: 需先在服务器上安装yum(虚拟机可使用挂载的方式安装) 安装配置所需要的环境运行指令: yum -y install gcc 进入解压文件执行make 指令进行编译 执 ...
- Android进程间通信
http://www.cnblogs.com/manuosex/p/3588634.html 一.Linux系统进程间通信有哪些方式? 1.socket: 2.name pipe命名管道: 3.mes ...
- uva11584
将课本上所述方法实现即可,代码如下: /* * Author: Bingo * Created Time: 2015/1/25 23:49:49 * File Name: uva11584.cpp * ...
- CentOS 6.5 + Nginx 1.8.0 + PHP 5.6(with PHP-FPM) 负载均衡源码安装
CentOS 6.5 + Nginx 1.8.0 + PHP 5.6(with PHP-FPM) 负载均衡源码安装 http://www.cnblogs.com/ppoo24/p/4918288.ht ...
- java的windows自动化-自动运行java程序
那么在一些工具齐全并且已经有了一定的写好的java程序的情况下(环境变量和软件见上一章http://www.cnblogs.com/xuezhezlr/p/7718273.html),如何自动化运行j ...
- LINUX 笔记-top命令
top命令经常用来监控linux的系统状况,比如cpu.内存的使用. top - :: up day, :, users, load average: 0.00, 0.01, 0.00 Tasks: ...
- ALV添加文字输入框
一.业务场景 在合同打印中,需要临时添加其他约定事项,在打印程序的ALV中添加其他事项字段,点击之后弹出文字输入窗口,点击确定,文字内容存表,并在ALV中展示,点击打印后,文字内容加载到smartfo ...
- Pdf文件处理组件对比(Aspose.Pdf,Spire.Pdf,iText7)
目的 因为公司是做医疗相关软件的,所以经常和文档打交道,其中就包含了Pdf.医院的Pdf(通常是他们的报告)都千奇百怪,而我们一直以来都是在用一些免费且可能已经没人维护了的组件来处理Pdf,所以就经常 ...