SQL分布式事务
数据库分布式事务概念:简而言之就是跨越了两个(或者更多)数据库的单个数据库引擎示例 就可以称之为分布式事务,平时用到的多库联查,就是分布式查询,只不过该事务是由本地资源管理器管理,对于用户而言就像操作本地事务一样
MSDN: http://msdn.microsoft.com/zh-cn/library/ms191440.aspx
提交/回滚 分布式事务分为两个阶段:
准备阶段
当事务管理器收到提交请求时,它会向该事务涉及的所有资源管理器发送准备命令。然后,每个资源管理器将尽力使该事务持久,并且所有保存该事务日志映像的缓冲区将被刷新到磁盘中。当每个资源管理器完成准备阶段时,它会向事务管理器返回准备成功或准备失败的消息。
提交阶段
如果事务管理器从所有资源管理器收到准备成功的消息,它将向每个资源管理器发送一个提交命令。然后,资源管理器就可以完成提交。如果所有资源管理器都报告提交成功,那么事务管理器就会向应用程序发送一个成功通知。如果任一资源管理器报告准备失败,那么事务管理器将向每个资源管理器发送一个回滚命令,并向应用程序表明提交失败。
事务提升:
事务默认是本地植物,如果在SP或者T-SQL中存在分布式查询或者远程调用SP,事务会默认被提升为分布式事务,也可以手动执行BEGIN DISTRIBUTED TRANSACTION 显示开启分布式事务,在对其他数据库服务器做分布式查询时,子控服务器数据库引擎会使用MS DTC(Distributed Transaction Coordinator)来管理事务,执行分布式查询或者远程调用的数据库引擎会作为主控服务器,
使用可提升事务的优点是在使用活动 TransactionScope 事务打开某个连接但不打开任何其他连接时,事务作为轻型事务提交,而不引发完全分布式事务的其他系统开销。
MSDN: http://msdn.microsoft.com/zh-cn/library/ms191156.aspx
分布式事务中使用Try Catch:
如果在 TRY 块的作用域内执行分布式事务且发生错误,执行将传递到关联的 CATCH 块。分布式事务进入不可提交状态。CATCH 块中的执行可能由管理分布式事务的 Microsoft 分布式事务处理协调器中断。发生错误时,MS DTC 将异步通知参与分布式事务的所有服务器,并终止分布式事务中涉及的所有任务。此类通知以关注消息的形式发送(TRY...CATCH 构造不处理此类通知),批处理将被终止。当批处理完成运行时,数据库引擎将回滚所有不可提交的活动事务。如果事务进入不可提交状态时未发送错误消息,则当批处理完成时,将向客户端应用程序发送错误消息,该消息指示检测到或回滚了一个不可提交的事务。
错误函数
TRY...CATCH 使用下列错误函数来捕获错误信息:
- ERROR_NUMBER() 返回错误号。
- ERROR_MESSAGE() 返回错误消息的完整文本。此文本包括为任何可替换参数(如长度、对象名或时间)提供的值。
- ERROR_SEVERITY() 返回错误严重性。
- ERROR_STATE() 返回错误状态号。
- ERROR_LINE() 返回导致错误的例程中的行号。
- ERROR_PROCEDURE() 返回出现错误的存储过程或触发器的名称。
最值得注意的是Catch的捕获级别,它是不是可以捕获所有的异常呢,当然不能,以下异常它就不能捕获,但是这些错误会别返回到运行批处理或者sp的级别:
1、 导致数据库引擎关闭并且错误级别大于等于20的错误不能捕获,但是如果数据库引擎未被关闭就可以捕获级别大于等于20的错误
2、 严重级别为 10 或更低的警告或信息性消息。
3、 需要关注的消息,如客户端中断请求或客户端连接中断。
4、 当系统管理员使用 KILL 语句终止会话时。
5、 编写错误,语法错误。
6、 语句级的错误,
下表列出并说明 SQL Server 数据库引擎所引起错误的严重级别。
严重级别 |
说明 |
0-9 |
返回不太严重的状态信息或报表错误的信息性消息。数据库引擎不会引起严重级别为 0 到 9 的系统错误。 |
10 |
返回不太严重的状态信息或报表错误的信息性消息。由于兼容性原因,数据库引擎在将错误信息返回到调用应用程序前将严重性级别从 10 转换为 0。 |
11-16 |
指示可由用户纠正的错误。 |
11 |
指示给定的对象或实体不存在。 |
12 |
特殊严重性,用于因特殊查询提示而不使用锁定的查询。在某些情况下,因为没有用锁保证一致性,由这些语句所执行的读取操作会产生不一致的数据。 |
13 |
指示事务死锁错误。 |
14 |
指示安全性相关错误,如权限被拒绝。 |
15 |
指示 Transact-SQL 命令中的语法错误。 |
16 |
指示可由用户纠正的常规错误。 |
17-19 |
指示无法由用户纠正的软件错误。请将问题通知系统管理员。 |
17 |
指示语句导致 SQL Server 用尽资源(如数据库的内存、锁或磁盘空间)或超出了系统管理员设置的某些限制。 |
18 |
指示数据库引擎软件中有问题,但可完成执行语句,并且可维护到数据库引擎实例的连接。每当出现严重级别为 18 的消息时均应通知系统管理员。 |
19 |
指示超出了不可配置的数据库引擎限制并且当前批处理已终止。严重级别为 19 或更高的错误消息将停止执行当前的批处理。严重级别为 19 的错误很少,必须由系统管理员或主要支持提供商更正。当引发严重级别为 19 的消息时,请与系统管理员联系。严重级别从 19 到 25 的错误消息均写入错误日志。 |
20-25 |
指示系统问题并且是致命错误,这意味着正在执行某语句或批处理的数据库引擎任务已停止运行。此任务记录了所发生事件的有关信息,然后终止。在大多数情况下,应用程序与数据库引擎实例的连接也可能终止。如果发生这种情况,该问题可能使应用程序无法重新连接。 此范围内的错误消息可以影响同一数据库中所有正在访问数据的进程,并可能指示数据库或对象已损坏。严重级别从 19 到 25 的错误消息均写入错误日志。 |
20 |
指示语句遇到了问题。由于该问题只影响了当前任务,数据库本身未必已经损坏。 |
21 |
指示遇到了影响当前数据库中所有任务的问题,但数据库本身未必已经损坏。 |
22 |
指示消息中所指定的表或索引因软件或硬件问题而损坏。 很少发生严重级别为 22 的错误。如果发生这种错误,请运行 DBCC CHECKDB 以确定数据库中的其他对象是否也已损坏。这种问题可能只是出现在缓存中而不存在于磁盘本身。如果发生此错误,请重新启动数据库引擎实例更正此问题。若要继续工作,则必须重新连接到数据库引擎实例;否则,请使用 DBCC 修复该问题。在某些情况下,可能需要还原数据库。 如果重新启动数据库引擎的实例不能解决此问题,那么问题就是出在磁盘上。有时,销毁错误消息中指定的对象可以解决此问题。例如,如果消息报告数据库引擎的实例在非聚集索引中发现了长度为 0 的行,则请删除该索引并重建。 |
23 |
指示整个数据库的完整性因硬件或软件问题而出现问题。 很少发生严重级别为 23 的错误。如果发生这种错误,请运行 DBCC CHECKDB 以确定损坏的程度。这种问题可能只是出现在缓存中而未出现在磁盘本身。如果发生此错误,请重新启动数据库引擎实例更正此问题。若要继续工作,则必须重新连接到数据库引擎实例;否则,请使用 DBCC 修复该问题。在某些情况下,可能需要还原数据库。 |
24 |
指示介质故障。系统管理员可能需要还原数据库。您可能还需要致电硬件供应商。 |
值得注意的是当远程调用sp时发生异常,这类异常属于语句级错误,当前sp不能通过Try catch捕获,只能由调用者捕获,就会导致远程SP不能显示提交/回滚。但是可以由DTC置为不可提交事务
MSDN: http://msdn.microsoft.com/zh-cn/library/ms179296.aspx
DTC:Distributed Transaction Coordinator ,分布式传输协调,该进程调用系统Microsoft Personal Web Server和Microsoft SQL Server。该服务用于管理多个分布式服务器