强类型Dataset使用事务(改进原有方法)
以下部份转自:http://blog.csdn.net/nfbing/article/details/5803980
关于强类型Dataset的用法和好处,我就不再多说,网上关于这方面的资料很多 , 感兴趣的话可以在GoOGLE搜一下。
我们直奔主题,好处是很多,但若使用事务的话就不方便了。最近通过查找国外的资料,总于找到解决的方法。经过自己测试发现很好用,所以把代码贴出来,给正处于这方面困惑的朋友解答:
首先写一个类文件,代码如下:
public class HelperTA
{ public static SqlTransaction BeginTransaction(object tableAdapter)
{
return BeginTransaction(tableAdapter, IsolationLevel.ReadUncommitted);
} public static SqlTransaction BeginTransaction(object tableAdapter, IsolationLevel isolationLevel)
{
// get the table adapter's type
Type type = tableAdapter.GetType(); // get the connection on the adapter
SqlConnection connection = GetConnection(tableAdapter); // make sure connection is open to start the transaction
if (connection.State == ConnectionState.Closed)
connection.Open(); // start a transaction on the connection
SqlTransaction transaction = connection.BeginTransaction(isolationLevel); // set the transaction on the table adapter
SetTransaction(tableAdapter, transaction); return transaction;
} /// <summary>
/// Gets the connection from the specified table adapter.
/// </summary>
private static SqlConnection GetConnection(object tableAdapter)
{
Type type = tableAdapter.GetType();
PropertyInfo connectionProperty = type.GetProperty("Connection", BindingFlags.NonPublic | BindingFlags.Instance);
SqlConnection connection = (SqlConnection)connectionProperty.GetValue(tableAdapter, null);
return connection;
} /// <summary>
/// Sets the connection on the specified table adapter.
/// </summary>
private static void SetConnection(object tableAdapter, SqlConnection connection)
{
Type type = tableAdapter.GetType();
PropertyInfo connectionProperty = type.GetProperty("Connection", BindingFlags.NonPublic | BindingFlags.Instance);
connectionProperty.SetValue(tableAdapter, connection, null);
} /// <summary>
/// Enlists the table adapter in a transaction.
/// </summary>
public static void SetTransaction(object tableAdapter, SqlTransaction transaction)
{
// get the table adapter's type
Type type = tableAdapter.GetType(); // set the transaction on each command in the adapter
PropertyInfo commandsProperty = type.GetProperty("CommandCollection", BindingFlags.NonPublic | BindingFlags.Instance);
SqlCommand[] commands = (SqlCommand[])commandsProperty.GetValue(tableAdapter, null);
foreach (SqlCommand command in commands)
command.Transaction = transaction; // set the connection on the table adapter
SetConnection(tableAdapter, transaction.Connection);
}
}
然后在你使用TableAdapter 的类文件中使用上面的类:
public int InsertTest(Book book)
{
SqlTransaction transaction = null; try
{
int? myresult = 0;
using (SKUTableAdapter barAdapter = new SKUTableAdapter())
{
transaction = HelperTA .BeginTransaction(barAdapter);
barAdapter.SP_InsertSku("dfsdf", "contentname", 2, "", ref myresult);
} using (UserEvaluateTableAdapter EvaluateAdapter = new UserEvaluateTableAdapter())
{
HelperTA .SetTransaction(EvaluateAdapter, transaction);
EvaluateAdapter.InsertQuery(Guid.NewGuid().ToString(), "username", "szevaluate", 2);
} int? result = 0;
using (tb_BookTableAdapter bookadapter = new tb_BookTableAdapter())
{
HelperTA .SetTransaction(bookadapter, transaction);
bookadapter.SP_CheckDuplicateEbook("title", "code", 2, System.DateTime.Now, ref result);
} transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
finally
{
transaction.Dispose();
} return 1;
}
以上内容转自nfbing的专栏:http://blog.csdn.net/nfbing/article/details/5803980
使用后发现不能针对TableAdapter自动生成的Insert/Update/Delete进行事务处理,可以对添加的查询(SQL或者存储过程)进行事务处理。所以如果想使用xxTableAdapter.Update(xxTable)一类的更新就有问题了。方法是自己写代码为TableAdapter加带事务的方法,但没有这个通用性好,需要每个去编写。
经过实验,将原来的代码部份更改,并更新相应的TableAdapter类即可实现较好的效果:
更新后类代码:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Reflection; /// <summary>
/// 为强类型的DataSet中的TableAdapter提供事务支持
/// </summary>
public class HelperTA
{
/// <summary>
/// 开始事务,第一个tableAdapter中使用,接受脏读
/// </summary>
/// <param name="tableAdapter"></param>
/// <returns>返回一个SqlTransaction</returns>
public static SqlTransaction BeginTransaction(object tableAdapter)
{
return BeginTransaction(tableAdapter, IsolationLevel.ReadUncommitted);
} /// <summary>
/// 开始事务,第一个tableAdapter中使用,可设置接受脏读及其它参数
/// </summary>
/// <param name="tableAdapter"></param>
/// <param name="isolationLevel">事务锁定行为</param>
/// <returns>返回一个SqlTransaction</returns>
public static SqlTransaction BeginTransaction(object tableAdapter, IsolationLevel isolationLevel)
{
// get the table adapter's type
Type type = tableAdapter.GetType(); // get the connection on the adapter
SqlConnection connection = GetConnection(tableAdapter); // make sure connection is open to start the transaction
if (connection.State == ConnectionState.Closed)
connection.Open(); // start a transaction on the connection
SqlTransaction transaction = connection.BeginTransaction(isolationLevel); // set the transaction on the table adapter
SetTransaction(tableAdapter, transaction); return transaction;
} /// <summary>
/// Gets the connection from the specified table adapter.
/// </summary>
private static SqlConnection GetConnection(object tableAdapter)
{
Type type = tableAdapter.GetType();
PropertyInfo connectionProperty = type.GetProperty("Connection", BindingFlags.NonPublic | BindingFlags.Instance);
SqlConnection connection = (SqlConnection)connectionProperty.GetValue(tableAdapter, null);
return connection;
} /// <summary>
/// 设置 table adapter 的连接属性(自动调用)
/// </summary>
private static void SetConnection(object tableAdapter, SqlConnection connection)
{
Type type = tableAdapter.GetType();
PropertyInfo connectionProperty = type.GetProperty("Connection", BindingFlags.NonPublic | BindingFlags.Instance);
connectionProperty.SetValue(tableAdapter, connection, null);
} /// <summary>
/// 将新的tableAdapter加入到事务中
/// </summary>
/// <param name="tableAdapter"></param>
/// <param name="transaction"></param>
public static void SetTransaction(object tableAdapter, SqlTransaction transaction)
{
// get the table adapter's type
Type type = tableAdapter.GetType(); // set the transaction on each command in the adapter
PropertyInfo commandsProperty = type.GetProperty("CommandCollection", BindingFlags.NonPublic | BindingFlags.Instance);
SqlCommand[] commands = (SqlCommand[])commandsProperty.GetValue(tableAdapter, null);
foreach (SqlCommand command in commands)
command.Transaction = transaction; //设置自动生成的增、删、改命令事务
PropertyInfo AdapterProperty = type.GetProperty("Adapter", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Static);
SqlDataAdapter adapter = (SqlDataAdapter)AdapterProperty.GetValue(tableAdapter, null);
if (adapter.InsertCommand != null) adapter.InsertCommand.Transaction = transaction;
if (adapter.UpdateCommand != null) adapter.UpdateCommand.Transaction = transaction;
if (adapter.DeleteCommand != null) adapter.DeleteCommand.Transaction = transaction; // set the connection on the table adapter
SetConnection(tableAdapter, transaction.Connection);
}
}
强类型Dataset使用事务(改进原有方法)的更多相关文章
- 强类型DataSet的使用简明教程
关于弱类型 DataSet的缺点: 无论何时从 DataSet检索值都是以Object类型返回,需要对它进行类型转换: 给其它开发者使用 时无法知道哪些列可用: 运行时才能知道所 有列名,数据绑定麻烦 ...
- Web Service 中返回DataSet结果的几种方法
Web Service 中返回DataSet结果的几种方法: 1)直接返回DataSet对象 特点:通常组件化的处理机制,不加任何修饰及处理: 优点:代码精减.易于处理,小数据量处理较快: ...
- uvm_tlm——TLM1事务级建模方法(一)
TLM(事务级建模方法,Transaction-level modeling)是一种高级的数字系统模型化方法,它将模型间的通信细节与函数单元或通信架构的细节分离开来.通信机制(如总线或者FIFO)被建 ...
- 【翻译自mos文章】当并行事务恢复进程在执行时,禁用并行事务恢复的方法
当并行事务恢复进程在执行时,禁用并行事务恢复的方法 How to Disable Parallel Transaction Recovery When Parallel Txn Recovery is ...
- 2强类型DataSet (2011-12-30 23:16:59)转载▼ 标签: 杂谈 分类: Asp.Net练习笔记 http://blog.sina.com.cn/s/blog_9d90c4140101214w.html
强类型DataSet (2011-12-30 23:16:59) 转载▼ 标签: 杂谈 分类: Asp.Net练习笔记 using System; using System.Collections.G ...
- 强类型DataSet (2011-12-30 23:16:59)转载▼ 标签: 杂谈 分类: Asp.Net练习笔记 http://blog.sina.com.cn/s/blog_9d90c4140101214w.html
强类型DataSet (2011-12-30 23:16:59) 转载▼ 标签: 杂谈 分类: Asp.Net练习笔记 using System; using System.Collections.G ...
- 什么叫强类型的DATASET ?对DATASET的操作处理?强类型DataSet的使用简明教程
强类型DataSet,是指需要预先定义对应表的各个字段的属性和取值方式的数据集.对于所有这些属性都需要从DataSet, DataTable, DataRow继承,生成相应的用户自定义类.强类型的一个 ...
- 使用强类型DataSet增加数据并获取自动增长的ID
使用强类型的DataSet可以方便的操作数据库:有时候我们会对表的ID设置为自动增长,并且需要在插入数据后获取新插入数据的ID,按以下方法即可达到目的: 一. 首先建立一个表,id为自动增加, ...
- Web Service 中返回DataSet结果大小改进
http://www.cnblogs.com/scottckt/archive/2012/11/10/2764496.html Web Service 中返回DataSet结果方法: 1)直接返回Da ...
随机推荐
- 第二天学习笔记:(MDN HTML学习、web安全策略与常见攻击、语义化)
一:Web入门 1:web文件命名 在文件名中应使用连字符(-).搜索引擎把连字符当作一个词的分隔符, 但不会以这种方式处理下划线. 养成在文件夹和文件名中使用小写,并且使用短横线而不是空格来分隔的习 ...
- vs2017 打开附带的localdb v13
查看自己本机装了哪些版本的localdb 打开数据库资源管理器 添加数据库连接 选择要连接的localdb版本,这里选择的是v13版本 添加数据库 新建一个test数据库 ...
- [古怪问题] Marshal.GetActiveObject 在管理员模式下无法正常运行
问题: var obj = Marshal.GetActiveObject("PowerPoint.Application") 该代码在管理员模式下运行无法正常获取正在运行的 PP ...
- Jexus 5.4.6 on CentOS 6.6
Mono 通过脚本安装 https://github.com/cjy37/linux-asp.net-installScript 版本 3.10 MongoDB 也可通过以上脚本安装 默认端口 270 ...
- Unity应用架构设计(1)—— MVVM 模式的设计和实施(Part 1)
初识 MVVM 谈起 MVVM 设计模式,可能第一映像你会想到 WPF/Sliverlight,他们提供了的数据绑定(Data Binding),命令(Command)等功能,这让 MVVM 模式得到 ...
- python3 + flask + sqlalchemy +orm(3):多对多关系
一篇文章有多个tag,一个tag也可以属于多篇文章,文章和tag存在多对多关系 config.py DEBUG = True #dialect+driver://root:1q2w3e4r5t@127 ...
- 公用表表达式(CTE)
在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以使用公用表表达式的方法.公用表表达式(Common Table ...
- SpringMvc的Url映射和传参案例(转)
Springmvc的基本使用,包括url映射.参数映射.页面跳转.ajax和文件上传 以前学习的时候写的代码案例,今天整理笔记的时候找到了,很久没有来园子了,发上来当个在线笔记用吧,免的时间长了又忘了 ...
- tracert traceroute
二者都用于探测数据包从源到目的经过路由的IP,但两者探测的方法却有差别.不同点:一.应用环境不同tracert是应用在windows下.traceroute则是应用在linux/BSD/router/ ...
- 服务器返回:type":"Buffer","data":
接口中返回"type":"Buffer","data":[32,232,175,183,233,151,174,229,177,177,23 ...