首先,我不会在页面中处理事务逻辑。编写某种业务类来完成此操作 - 一个服务、数据实用程序类或其他可以从ASP.Net抽象出来的东西。
其次,如果您使用的数据库可以订阅分布式事务(如SQL Server),则可以考虑使用TransactionScope类(位于System.Transactions命名空间中,引用System.Transactions.dll)。
using(TransactionScope scope = new TransactionScope())
{
SaveObjectOne(); //these are just psuedo-code statements
SaveObjectTwo(); //replace these with your code that saves various objs
SaveObjectThree();
scope.Complete(); //this commits the transaction, unless exception throws
}
TransactionScope实现了IDisposable接口,因此当using调用Dispose()时,如果从未调用Complete(),事务将回滚。使用TransactionScope需要启用分布式事务协调器。
在ado.net 2.0中,事务非常简单。我建议使用Transactionscope,并让框架为您管理事务:
阅读{{link1:MSDN}}上的所有内容:
Transaction Flow Management
Transaction scopes can nest both directly and indirectly. A direct scope nesting is simply one scope nested inside another, as shown in Example 5.
Example 5. Direct scope nesting
using(TransactionScope scope1 = new TransactionScope()) { using(TransactionScope scope2 = new TransactionScope()) { scope2.Complete(); } scope1.Complete(); }
An indirect scope nesting occurs when calling a method that uses a
TransactionScope
from within a method that uses its own scope, as is the case with theRootMethod()
in Example 6.Example 6. Indirect scope nesting
void RootMethod() { using(TransactionScope scope = new TransactionScope()) { /* Perform transactional work here */ SomeMethod(); scope.Complete(); } } void SomeMethod() { using(TransactionScope scope = new TransactionScope()) { /* Perform transactional work here */ scope.Complete(); } }
楼主说这个集合管理了事务中所有其他对象的保存,因此在这里放置事务代码似乎是显而易见的。如果您正在使用ADO.Net,则似乎最简单的选项是在集合中打开连接并开始事务,然后将其传递给每个其他对象。我假设这里的每个对象都继承自一个层超类型类,并且您正在使用SQL Server。
public void Save()
{
using (SqlConnection connection = new SqlConnection("Connection String"))
{
using (SqlTransaction trans = connection.BeginTransaction())
{
foreach (BusinessObject obj in this)
{
obj.Save(connection);
}
trans.Commit();
}
}
}