这一节,我要说明的是在数据集中添加事务,
在这里说明一下事务的必要性:
大多数基于 web 的电子邮件客户端都使用一个网格列出每条消息,除了包含邮件的信息(主题、发送者等等)外,还包括一个复选框。该界面允许用户删除多个消息,方法是先勾选上它们,再单击“Delete Selected Messages ”按钮。在用户通常编辑多条不同记录的情况下,一个批量编辑界面则是一项理想的选择。用不着让用户对每条要修改的记录,单击Edit ,进行修改,然后单击 Update ,批量编辑界面里每条记录都有其各自的编辑界面。用户可以快速地修改需要更改的那几行,然后单击“Update All” 按钮保存这些更改。在本系列教程中,我们将探讨如何创建插入、编辑和删除批量数据的界面。
执行批操作时,重要的是确定是否会出现批操作中的某些操作可能成功而其它操作可能失败的情况。考虑一个批量删除界面:如果选择的第一条记录删除成功,但第二条由于违反外健约束而失败时,会出现什么情况?第一条记录的删除操作应该回滚?还是可以接受删除第一条记录?
如果想把批操作作为原子操作 对待,即所有的操作步骤要么都成功要么都失败,则需要对数据访问层进行扩展以支持数据库事务 。数据库事务确保INSERT 、UPDATE 和 DELETE 语句集的原子数在事务的保护下执行,大多数当代数据库系统都支持数据库事务特性。
事务概述
大多数数据库都支持事务,它可以把多个数据库命令当成一个逻辑单元进行处理。保证组成事务的数据库命令是原子级表示所有的命令要么都失败要么都成功。
一般来说,事务通过 SQL 语句来实现,使用如下的模式:
- 指示事务的开始。
- 执行构成事务的 SQL 语句。
- 如果步骤 2 中的一个语句出错,则回退该事务。
- 如果步骤 2 中的所有语句都没有错误, 则提交该事务。
位于App_Code 文件夹的 DAL 子文件夹中。在 DAL 文件夹中创建一个名为 TransactionSupport 的子文件夹,并在里面添加一个名为s_courseinfoTableAdapter.TransactionSupport.cs 的新的类文件。该文件将保持s_courseinfoTableAdapter的部分实现,s_courseinfoTableAdapter 包含使用事务执行数据修改的方法。
在类中添加 如下代码
注意 这里使用的类是partical 部分类,将数据库事务操作封装在类的内部
代码 namespace GYsmsTableAdapters
{
/// <summary>
///s_courseinfoTableAdapter 的摘要说明
/// </summary>
partial class s_courseinfoTableAdapter
{
private SqlTransaction _transaction;
private SqlTransaction Transaction
{
get
{
return this._transaction;
}
set
{
this._transaction = value;
}
}
}
在加入 开始事务的方法
{
// Open the connection, if needed
if (this.Connection.State != ConnectionState.Open)
this.Connection.Open();
// Create the transaction and assign it to the Transaction property
this.Transaction = this.Connection.BeginTransaction();
// Attach the transaction to the Adapters
foreach (SqlCommand command in this.CommandCollection)
{
command.Transaction = this.Transaction;
}
this.Adapter.InsertCommand.Transaction = this.Transaction;
this.Adapter.UpdateCommand.Transaction = this.Transaction;
this.Adapter.DeleteCommand.Transaction = this.Transaction;
}
再下来是提交,和回滚事务操作
{
// Commit the transaction
this.Transaction.Commit();
// Close the connection
this.Connection.Close();
}
public void RollbackTransaction()
{
// Rollback the transaction
this.Transaction.Rollback();
// Close the connection
this.Connection.Close();
}
在类中添加事务更新方法
/// 事务性更新
/// </summary>
/// <param name="dataTable"></param>
/// <returns></returns>
public int UpdateWithTransaction(GYsms.s_courseinfoDataTable dataTable)
{
this.BeginTransaction();
try
{
// Perform the update on the DataTable
int returnValue = this.Adapter.Update(dataTable);
// If we reach here, no errors, so commit the transaction
this.CommitTransaction();
return returnValue;
}
catch
{
// If we reach here, there was an error, so rollback the transaction
this.RollbackTransaction();
throw;
}
}
这样就完成了DAL层的事务添加了,
这样,在BLL层添加事务性的方法,事务性添加,事务性删除
/// 批量事务性更新
/// </summary>
/// <param name="products"></param>
/// <returns></returns>
public int UpdateWithTransaction(GYsms.s_courseDataTable Coursetable)
{
return Adapter.UpdateWithTransaction(Coursetable);
}
/// <summary>
/// 批量事务性删除
/// </summary>
/// <param name="productIDs"></param>
public void DeleteCourseWithTransaction
(System.Collections.Generic.List<int> CourseIDs)
{
// Start the transaction
Adapter.BeginTransaction();
try
{
// Delete each product specified in the list
foreach (int CourseID in CourseIDs)
{
Adapter.Delete(CourseID);
}
// Commit the transaction
Adapter.CommitTransaction();
}
catch
{
// There was an error - rollback the transaction
Adapter.RollbackTransaction();
throw;
}
}
在WEB层的Course,aspx网页上有一个批量删除的方法,这样写就行
{
List<int> delnums = new List<int>();
foreach (RepeaterItem Item in Repeater1.Items)
{
CheckBox ck = (CheckBox)Item.FindControl("ckbIndex");
Label lab = (Label)Item.FindControl("Labelid");
if (ck.Checked)
{
int j = Convert.ToInt32(lab.Text);
delnums.Add(j);
}
}
CourseAPI.DeleteCourseWithTransaction(delnums);
AlertMessage.Redirect(this, "删除成功", "Course.aspx");
}
我在帖上在Repeater里面的代码
<ItemTemplate>
<tr><td class="chk"><asp:CheckBox runat="server" ID="ckbIndex" /></td>
<td><asp:Label ID="Labelid" runat="server" Text='<%#Eval("id") %>'></asp:Label></td>
<td><asp:Label ID="Labelkid" runat="server" Text='<%#Eval("kid") %>'></asp:Label></td>
<td><asp:Label ID="Labelkname" runat="server" Text='<%#Eval("kname") %>'></asp:Label></td>
<td><asp:Label ID="Labelteacher" runat="server" Text='<%#Eval("teacher") %>'></asp:Label></td>
<td><asp:Label ID="Labelterm" runat="server" Text='<%#Eval("term") %>'></asp:Label></td>
<td><div><span><img src="images/edt.gif" alt="编辑" width="16" height="16" /><a href="Course_edit.aspx?action=edit&id=<%# Eval("id") %>" title="">编辑</a>
<img src="images/del2.gif" alt="删除" width="16" height="16" /><a href="course.aspx?action=del&id=<%# Eval("id") %>" title="" onclick="return confirm('真的要删除吗?');" >删除</a></span></div>
</ItemTemplate>
</asp:Repeater>
这样就完成数据集事务的说明了,下一节,我会写上Courseadd.aspx的页面,批量添加课程信息.