分布式事务是在 Windows Installer 自定义操作中启用数据库升级回滚的好主意吗?

发布于 2024-09-13 16:56:35 字数 870 浏览 11 评论 0原文

我已经无法满足 WiX 中提供的 Sql Server 自定义操作的需求,因此我大胆地使用 Deployment Tools Foundation 创建自己的操作。我想成为一个好公民并确保我的支持回滚。但最好的方法是什么?

我需要支持 SQL Server 2005 及更高版本的所有版本。

在我看来,问题在于 Windows Installer 分两个阶段工作:它完成工作,同时存储撤消信息。然后,当所有部分就位时,它要么提交(删除撤消信息),要么回滚。

这意味着标准交易无法完成这项工作。它们必须在我的执行自定义操作中完成,而且我以后没有机会回滚它们。

我考虑过对数据库进行仅复制备份如有必要,我可以在回滚操作中进行恢复,但我认为这种方法虽然简单,但也有缺点。例如,我不知道我们的数据库将有多大 - 因此我无法保证目标计算机上有可用空间来保存备份。此外,备份和恢复可能需要一段时间才能完成,而且我不希望典型安装(不​​发生回滚)变得不必要的缓慢。

因此,这让我想到了我当前最喜欢的想法:确保分布式事务协调器已启动,然后在进行更改之前初始化分布式事务,然后在适当的自定义操作中提交或回滚它。

看来我可以使用 TransactionInterop 的成员类来导出 cookie,这将使我能够在不同的自定义操作之间共享事务。

有此类经验的人可以说它是否可能有效吗?

I've outgrown the Sql Server custom actions available in WiX, so I'm taking the bold step of creating my own using Deployment Tools Foundation. I want to be a good citizen and make sure that mine support rollback. But what's the best way of doing it?

I need to support SQL Server 2005 and later, all editions.

The problem, as I see it, is that Windows Installer works in two phases: it does the work, storing undo information as it goes. Then, when all the pieces are in place it either commits (deleting the undo information) or does a rollback.

This means that standard transactions won't do the job. They would have to be completed inside my Execute custom action, and I wouldn't get a chance to roll them back later.

I've considered taking a copy-only backup of the database that I can restore in the rollback action if necessary but I think this approach, whilst simple has shortcomings. I don't know how big our databases will get, for example - so I can't guarantee that there will be space available to hold the backup on the target machine. Also, backup and restore can take a while to complete, and I don't want typical installs (where rollback doesn't happen) to be unnecessarily slow.

So that brings me to my current favoured idea: make sure the Distributed Transaction Coordinator is started up, then initialise a Distributed Transaction before making changes, then either committing it or rolling it back in the appropriate custom actions.

It seems I can uses the members of the TransactionInterop class to export a cookie that will enable me to share the transaction between my different custom actions.

Can anyone with experience of this kind of thing say if it is likely to work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

自此以后,行同陌路 2024-09-20 16:56:35

某些数据库/实例操作无法在事务内完成(例如 CREATE/ALTER/DROP ENDPOINT),而其他操作则无法在分布式事务内完成(例如 SAVE TRANSACTION)。因此,您将根本无法在提议的计划中执行这些操作。此外,当在未提交的事务中运行时,您的数据库升级脚本必须能够正常工作。

我想说的是,沿着备份/恢复路径(或者创建数据库快照并在回滚时从快照恢复,但需要 EE 的缺点)的风险较小。

另一种选择是为升级期间运行的每个 do 脚本设置一个 undo 脚本,并在回滚期间运行撤消脚本并消除安装的影响。我知道这是一个困难问题,可能会使必须开发(和测试......)的脚本数量增加一倍,并且需要一些严格的开发人员纪律。

Some database/instance operations cannot be done inside a transaction (eg. CREATE/ALTER/DROP ENDPOINT), and other operations cannot be done inside a distributed transaction (eg. SAVE TRANSACTION). So you won't be able to do them at all in your proposed plan. Also your DB upgrade scripts will have to all work correctly when run inside an uncommitted transaction.

I would say that there are fewer risks of going down the backup/restore path (or alternatively creating a database snapshot and restoring from the snapshot on rollback, with the drawback of requiring EE).

Also an option is to have an undo script for every do script run during upgrade, and have the undo script run during rollback and remove the effects of the installation. I understand that this is a hard problem, probably doubles the amount of scripts that have to be developed (and tested...) and requires some serious developer discipline.

牵你手 2024-09-20 16:56:35

多年来,我已经使用 SQL 脚本完成了相当多的安装程序,我认为它只适合简单的数据库,例如这里是我的带有本地 MSDE / MySQL 数据库的 VB 应用程序,或者这是我的本地代码存储当我们等待在其他地方同步它时,进行表查找和临时提交。

一旦您进入工业强度重型企业应用程序类型的情况,我喜欢将我的数据库配置从安装程序中取出并作为首次运行类型故事放入应用程序中。您可以使用 C# 完成更多繁重的工作,而不受 MSI 的限制。

I've done quite a few installers with SQL scripts over the years and I've kind of come to the opinion that it's only suited for simple databases like here's my VB app with a local MSDE / MySQL database or here's my local store for code table lookups and temporary commits while we wait to sync it somewhere else.

Once you get into industrial strength heavy lifting enterprise app type situations I like to get my DB configuration out of the installer and into the application as a first run type story. You can do a lot heavier lifting with C# there and not be constrained by MSI.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文