今天上班遇到这样的业务:将删除的用户信息记录到记录表,再删除用户表中的信息。

可以说是不幸也可以说是幸运的。

在以往遇到这样的业务,我会考虑到各种出现异常或者失败的情况。在删除一张表数据失败的情况,对另一张表的操作也要还原。

但是今天,删除用户表失败时,无法删除刚刚记录到记录表的信息,因为没有一个条件可以筛选出我刚刚记录到记录表中的数据。

想到了代码块事务:TransactionScope

TransactionScope类的命名空间是System.Transactions,位于 System.Transactions.dll。

在.net2.0后出现了ransactionScope类,大大简化了事务的设计。并且该类型是线程安全的。

在实例化 TransactionScope 通过 new 语句中,事务管理器确定哪些事务参与进来。 一旦确定,该范围将始终参与该事务。

如果在事务范围内未不发生任何异常 (即之间的初始化 TransactionScope 对象并调用其 Dispose 方法),则范围所参与的事务可以继续。如果在事务范围内发生异常,参与到其中的事务将回滚。

当应用程序完成所有工作时它想要在事务中执行,应调用 Complete 方法一次,以通知该事务管理器是可接受,即可提交事务。未能调用此方法中止事务。

调用 Dispose 方法将标记事务范围的末尾。 在调用此方法之后所发生的异常不会影响事务。

以下两个方法使用最多“”

Complete()      指示范围内的所有操作都已成功都完成。
          Dispose()        结束事务范围。

我有一张订单表,一张客户表

客户表脚本

CREATE TABLE [dbo].[Customer](
[ID] [int] IDENTITY(1,1) NOT NULL,
[CustomerName] [nvarchar](32) NOT NULL,
[SubTime] [datetime] NOT NULL,
[CustomerPwd] [nvarchar](32) NOT NULL,
CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] GO

订单表脚本

CREATE TABLE [dbo].[OrderInfo](
[ID] [int] IDENTITY(1,1) NOT NULL,
[OrderId] [nvarchar](255) NOT NULL,
[SubTime] [datetime] NOT NULL,
[CustomerID] [int] NOT NULL,
CONSTRAINT [PK_OrderInfo] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] GO ALTER TABLE [dbo].[OrderInfo] WITH CHECK ADD CONSTRAINT [FK_CustomerOrderInfo] FOREIGN KEY([CustomerID])
REFERENCES [dbo].[Customer] ([ID])
GO ALTER TABLE [dbo].[OrderInfo] CHECK CONSTRAINT [FK_CustomerOrderInfo]
GO  

客户表Customer和订单表OrderInfo是一对多的关系,一个客户可以由多个订单。

增加一条客户信息和两条订单信息

 /// <summary>
/// 添加客户与订单
/// </summary>
private void AddCustomerOrderInfo()
{
try
{
using (TransactionScope scope = new TransactionScope())
{
TestEntities db = new TestEntities();
Customer customer = new Customer() { CustomerName = "admin123", CustomerPwd = "", SubTime = DateTime.Now};
db.Customer.Add(customer);
db.SaveChanges(); OrderInfo orderInfo1 = new OrderInfo() { OrderId = "", SubTime = DateTime.Now, Customer = customer };
OrderInfo orderInfo2 = new OrderInfo() { OrderId = "", SubTime = DateTime.Now, Customer = customer };
db.OrderInfo.Add(orderInfo1);
db.OrderInfo.Add(orderInfo2);
db.SaveChanges();//工作单元模式。 //提交事务,当失败的时候自动回滚。
scope.Complete();
}
}
catch (TransactionAbortedException ex)
{ }
catch (Exception ex)
{ }
}

最新文章

  1. SQL SERVER出现大量一致性错误的解决方法
  2. 彩票号码OC呈现
  3. PL/SQL错误提示 database character set(AL32UTF8) and Client character set(ZHS16GBK) are different
  4. mysql数据库优化小结
  5. 初次使用erlang的concurrent
  6. adId、idfv
  7. 笔记8:winfrom连接数据库DBHelp
  8. 【转】HTML,CSS,font-family:中文字体的英文名称 (宋体 微软雅黑)
  9. 使用C#三维绘图控件快速搭建DXF查看程序
  10. cocos2d-x 3.0 alpha1 生成Qt qch帮助文档
  11. LeetCode 11
  12. java进阶计划
  13. 一个cocoapods问题的解决,希望能帮助到遇到相似情况的人
  14. redis13---事务处理。
  15. 使用postMessage实现跨域 解决&#39;Failed to execute &#39;postMessage&#39; on &#39;DOMWindow&#39;&#39;
  16. ImportError: No module named _tkinter, please install the python-tk package ubuntu运行tkinter错误
  17. TF, IDF和TF-IDF
  18. MySQL 数据类型说明解释
  19. tensorflow学习5----GAN模型初探
  20. hdu5335(bfs,贪心)

热门文章

  1. Docker Mysql数据库主从同步配置方法
  2. SQL SERVER 批量生成编号
  3. grokking deep learning
  4. SparkStreaming:关于checkpoint的弊端
  5. Java多线程:CountDownLatch、CyclicBarrier 和 Semaphore
  6. Java多线程:多线程基础知识
  7. 在java.util中有EventListener接口:所有事件监听者都要实现这个接口。
  8. Vivado Design Suite用户指南之约束的使用第二部分(约束方法论)
  9. 为何GET只发一次TCP连接,POST发两次TCP连接
  10. 115、如何构建Android MVVM 应用框架(转载)