强类型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 ...
随机推荐
- UITextField 基本设置
_myAccount = [[UITextField alloc]init]; _myAccount.frame = CGRectMake(, , , ); _myAccount.background ...
- CentOS7开启docker远程访问并在idea中连接使用
CentOS7开启docker远程访问并在idea中连接使用 1.编辑/usr/lib/systemd/system/docker.service,配置远程访问.主要是在[Service]这个部分,添 ...
- py3下怎么用StringIO
try: from StringIO import StringIO except ImportError: from io import StringIO
- IntelliJIdea 2016.2 使用 tomcat 8.5 调试spring的web项目时,bean被实例化两次导致timer和thread被启动了两遍的问题的解决
今天新搭建了一个spring的web项目,项目启动时会启动一个线程,线程里定时执行任务,另外还启动了一个定时器,每秒钟统计系统吞吐量等业务性能数据.但是调试的时候惊奇的发现定时器和线程均被启动了两次. ...
- MySQL安装、配置、测试
MySQL安装.配置.测试(win7_64bit) 目录 1.概述 2.本文用到的工具 3.MySQL安装配置 4.Java访问MySQL测试 5.注事事项 6.相关博文 >>看不清的图片 ...
- Delphi目录监控、目录监听
资料地址: 1.https://www.cnblogs.com/studypanp/p/4890970.html 单元代码: (************************************ ...
- 【资料下载区】【GK101固件】更新日期2017/1/11
<GK101任意波发生器>升级固件发布(版本:1.0.2build539)<GK101任意波发生器>升级固件发布(版本:1.0.2build851)<GK101任意波发生 ...
- caffe网络结构可视化在线工具
http://ethereon.github.io/netscope/#/editor shift+enter
- rpc error: code = Internal desc = stream terminated by RST_STREAM with error code: PROTOCOL_ERROR
使用grpc-go调用grpc服务端时,出现rpc error: code = Internal desc = stream terminated by RST_STREAM with error c ...
- OraclePLSQL编程
PL/SQL编程 pl/sql(procedural language/sql)是Oracle在标准的sql语言上的扩展.pl/sql不仅允许嵌入式sql语言,还可以定义变量和常量,允许使用条件语句和 ...