我记得大学时说过:
默认情况下,在一个事务下不能参与对 2 个或多个数据源进行插入、删除和更新
请考虑这段代码:
begin tran Insert2
begin try
Insert into Northwind.dbo.Categories ([CategoryName], [Description])
values ('New Category', 'Some Desc')
Insert into [TestDB].[dbo].[tblRate]([Year], [Month], [Rate])
values(1111, 1, null) <-- Failed because of null value
commit tran Insert2
end try
begin catch
rollback tran Insert2;
throw;
End catch
我无法创建一个插入在Northwind
数据库上执行而另一个插入不执行的脚本TestDB
,但回滚无法删除Northwind
数据库上插入的行。
问题 1) 事务是在 a 下管理Instance
还是在 a 下管理Database
?我的意思是,给定实例中存在的多个数据库可以参与一个事务吗?
问题 2) 如果TestDB
存在于 SQL Server 的另一个实例中(例如MyServer2
),是否可以将其包含在当前实例的一个事务中(例如MyServer1
)。
您能给我看一下示例代码吗?
谢谢
这听起来像是断章取义的,因为按照目前的写法,没有任何其他细节,这是一个不正确的陈述。
您可以将多个 DML 语句 (
INSERT
、UPDATE
、DELETE
) 应用于同一事务下的多个数据源。在 SQL Server 中,此类事务只需围绕您想要在同一事务中参与的所有 DML 语句显式定义即可。例如:在上面的示例中,两个不同的语句影响两个不同的表,并且都在事务结束时回滚。
如果没有显式指定它们周围的事务,则每个语句都会作为其自己的事务以原子方式单独执行,而不是每个语句。
抱歉,我不明白你在这里想说什么。您能否提供dbfiddle.uk的示例?
是的,多个数据库可以参与同一个事务。事务可以定义为您想要的粒度,也可以定义为宏观,并且可以包含任意数量的数据源,无论是否位于同一数据库中。
是的,这就是所谓的分布式事务。
当然,这里是上述分布式事务文档中示例的一些代码:
在此示例中,删除发生在表的本地副本上
JobCandidate
,也发生在另一个 SQL Server 实例的远程副本上,所有这些都在同一事务中。如果发生错误并发生回滚,则这两项更改也将被撤消。请注意,为了使用分布式事务,需要在远程服务器上启用并正确配置Microsoft 分布式事务协调器 (MS DTC) 。
如果您想做两项更改,并且第二项不应触及第一项 - 只需将它们分开即可。
事务在“会话”下管理。您连接到服务器,直到您断开连接 - 这就是一个会话。对该服务器上任意数量的数据库的任何更改都是一个事务。从技术上讲:您进行更改,它被写入日志的脏页中,您提交 - 应用于该服务器管理的所有存储设备的所有更改,您回滚 - 您在此事务中写入脏页的所有更改都将被放弃。事务中包含多少个数据库并不重要。
如果您的一个表实际上是到另一台服务器的链接表,那么此类表的每个单独更新实际上都是该辅助服务器上且在事务机制之外的新会话。
是的,如果您有两个“数据源”,它们不能位于同一事务中。“数据源”通常定义从客户端到服务器的连接。如果您有两个“数据源”,则意味着两个连接,因此意味着两个独立的事务。