C# - 业务层中事务的使用(SQLServer 2005+,Oracle) - 很好的例子

发布于 2024-11-15 09:23:37 字数 712 浏览 7 评论 0原文

我将使用三层架构构建一个服务,我真的很担心如何以事务方式处理操作。

我知道我有 2 个选择:IDbTransactionTransactionScope...但我并没有真正决定选择哪一个,尽管我做了很多研究。

我会选择 TransactionScope,但我不想涉及 DTC...另外我需要对 SQLServer2005 和 Oracle 的支持。 (我知道我一次只需要打开一个连接)

我希望看到它们在这两种情况下的使用的良好示例/模式...好的链接就可以了。

类似于 BL 类和 DAL 类的外观...以及事务/连接是如何在它们之间创建和承载的。

编辑1: 我正在寻找某种实现(但对于两个选项):

using(var scope = new TransactionScope())
{
    // transactional methods
    datalayer.InsertFoo();
    datalayer.InsertBar();
    scope.Complete();
}

Edit2: 由于 Denis 为我提供了一个非常好的选择...我仍然在等待有人向我展示一个使用“TransactionScope”在业务层和数据层之间进行交互的模型的好示例,

谢谢。

I am gonna build a service using 3-tier architecture and I am really worried about how to handle operations in a transacted way.

I know I have 2 options: IDbTransaction and TransactionScope... but I am not really decided for which one to go, although I did a lot of research.

I would go for TransactionScope but I don't want to involve DTC... plus I need support for SQLServer2005 and Oracle. (I am aware that I need to have only one connection opened at a time)

I would like to see good examples/patterns of their usage for both cases... Good links would do just fine.

Something like how a BL class and DAL class would look like... but also how transaction/connections are created and carried between them.

Edit1:
I am looking for somekind of implementation of this (but for both options):

using(var scope = new TransactionScope())
{
    // transactional methods
    datalayer.InsertFoo();
    datalayer.InsertBar();
    scope.Complete();
}

Edit2:
Since Denis offered me a very good alternative... I still wait for somebody to show me a good example of a model with interaction between business layer and data layer using 'TransactionScope'

Thank you.

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

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

发布评论

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

评论(4

双手揣兜 2024-11-22 09:23:37

我目前在这种情况下使用的是多个存储库和多个 UnitOfWork 方法。假设您有 CustomerRepository 和 InvoiceRepository。如果您需要执行此操作:

customerRepository.Add(customer);
invoiceRepository.Add(bill);

并将这两个作为事务,那么我所做的就是在存储库创建时为它们提供相同的 UnitOfWork,例如:

IUnitOfWork uow = UnitOfWork.Start();
ICustomerRepository customerRepository = new CustomerRepository(uow);
IInvoiceRepository invoiceRepository = new InvoiceRepository(uow);

这样上面的语句现在就变成了:

customerRepository.Add(customer);
invoiceRepository.Add(bill);
uow.Commit();

所有魔法都在下面,取决于您使用的内容数据技术(要么是像NHibernate这样的ORM,要么是原始的ADO.NET——在大多数情况下不推荐这样做)。

有关存储库模式和 UnitOfWorks 的一个很好的示例,请阅读本教程,但请注意,其中不能有多个处于活动状态的 UnitOfWorks(实际上很少有应用程序需要它,因此没有真正的问题)。
另外,本教程使用 NHibernate,因此如果您不熟悉 ORM 概念,我建议您了解它(如果您的时间表允许)。

还有一件事:这里还有更高级的模式,比如每个会话的会话等等,但这是高级的东西,我现在正在绞尽脑汁,如果你想看看 uNhAddIns 项目(对于 NHibernate 也)

What I use in this case currently is multiple repositories and multiple UnitOfWork approach. Lets say that you have CustomerRepository and InvoiceRepository. If you need to do this:

customerRepository.Add(customer);
invoiceRepository.Add(bill);

and have these two as a transaction, then what I do is on repository creation I give them the same UnitOfWork, like:

IUnitOfWork uow = UnitOfWork.Start();
ICustomerRepository customerRepository = new CustomerRepository(uow);
IInvoiceRepository invoiceRepository = new InvoiceRepository(uow);

so that statements above are now:

customerRepository.Add(customer);
invoiceRepository.Add(bill);
uow.Commit();

All magic is beneath, dependent on what you use as data technology (either ORM like NHibernate, or maybe raw ADO.NET - and this is not recommended in most cases).

For a good example on repository pattern and UnitOfWorks, go through this tutorial, but note that in it you can't have multiple UnitOfWorks active (and few applications need that actually, so no real problem there).
Also, the tutorial uses NHibernate, so if you are not familiar with ORM concept, I suggest you get into it (if your timetable allows it).

one more thing: you also have more advanced patterns here, like session per conversation and such, but this is advanced stuff in which I'm having my head wrapped in right now, if you want take a look at uNhAddIns projects (for NHibernate also)

温柔女人霸气范 2024-11-22 09:23:37

我会选择 TransactionScope,因为它使用起来更简单,因为您不需要继承事务对象,或将其传递给每个方法。这是环境。这意味着,大多数时候,开发人员几乎可以忘记事务,编写很酷的面向业务的方法,然后在真正需要的地方添加事务包装器(使用“using”)。 (我知道这听起来很田园诗般的感觉,但也差不多就是这样了)。

与普遍看法相反,使用 TransactionScope 并不意味着 MSDTC 会参与其中,请参阅此处进行回顾:

避免不必要的分布式事务升级

而且,如果您确实需要分布式事务,好吧,如果没有 MSDTC,你打算怎么做呢? TransactionScope 的有趣之处在于,如果需要,它将升级到 MSDTC,而无需更改代码中的任何内容。

I would go for TransactionScope, because it's much simpler to use, as you don't need to carry over a transaction object, or pass it to every method. It's ambient. It means, most of the time, developers can almost forget about transactions, write cool business-oriented methods, and then, later, add transaction wrappers (using 'using') where it's really needed, afterwards. (sounds idyllic I know, but it's almost that).

Contrary to popular belief, using a TransactionScope does not means MSDTC will be involved, see here for a recap on this:

Avoid unwanted Escalation to Distributed Transactions

And, if you really need to have a distributed transaction, well, how do you plan to do it without MSDTC anyway? What's interesting with TransactionScope again, is it will escalate to MSDTC if needed, without changing nothing in your code.

单调的奢华 2024-11-22 09:23:37

您可以通过实现在业务层中使用的瘦包装器来抽象这两种技术。让我们这样说:

using (IUnitOfWork unitOfWork = UnitOfWork.Start())
{
    // do something
    unitOfWork.Commit();
}

然后您可以使用仅打开数据库事务的实现。如果您需要涉及另一个事务系统,只需将工作单元实现切换到打开 TransactionScope 而不是简单的数据库事务的系统即可。

You can abstract these two technologies by implementing a thin wrapper, which you use in your business layer. Lets say something like:

using (IUnitOfWork unitOfWork = UnitOfWork.Start())
{
    // do something
    unitOfWork.Commit();
}

You can then use an implementation that just opens a database transaction. If you need to involve another transactional system, you just switch the unit of work implementation to one which opens a TransactionScope rather than the simple database transaction.

长途伴 2024-11-22 09:23:37

UnitOfWork 模式非常适合清晰的事务处理(除其他外)。以下是一些重型应用程序中使用的模式的良好实现:

https ://github.com/NikGovorov/Taijutsu/tree/master/Sources/Sources/Taijutsu-Infrastruct

虽然你必须为你选择的 ORM 实现 DataProvider (NH,EF,...)但这相当微不足道。

UnitOfWork pattern is perfect for clear transaction handling (among other things). Here's a good implementation of the pattern used in some heavy duty applications:

https://github.com/NikGovorov/Taijutsu/tree/master/Sources/Sources/Taijutsu-Infrastructure

Although you'd have to implement DataProvider for ORM of your choice (NH, EF,...) but it's fairly trivial.

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