解决大批量数据TransactionScope出错问题
来源:互联网 发布:知画生孩子视频 编辑:程序博客网 时间:2024/06/03 23:51
TransactionScope 是.net 提供的可提升事务环境,开发软件的时候非常方便,但是在大数据量处理的时候,会莫名我出错,检查代码没有任何的错误
解决这个错误的方法:不用TransactionScope ,自己写一个用MSDTC的事务就可以了。
我的项目里面用的就是这TransactionScope ,但是在导入数据的时候,超过1万条记录(3张表)的时候,系统就报错了。数据在7000条的时候,没有任何问题。没有解决办法。
最好只好改变思路,不使用TransactionScope ,参照微软的COM+1.5的帮助,写了下面的。插入5万条记录的时候,包括从客户端传到服务器端共花了7分钟,没有任何问题。
在.net 2.0的环境下,建议大家不要用TransactionScope 。
public enum TransactionScopeOption
{
Suppress = TransactionOption.NotSupported,
Required = TransactionOption.Required,
RequiresNew = TransactionOption.RequiresNew
}
public class TransactionScope : IDisposable
{
bool m_Consistent = false;
public void Complete()
{
if (m_Consistent == false)
{
m_Consistent = true;
ContextUtil.MyTransactionVote = TransactionVote.Commit;
}
else
{
throw new InvalidOperationException("Cannot call Complete() more than once");
}
}
public TransactionScope()
: this(TransactionScopeOption.Required)
{ }
public TransactionScope(TransactionScopeOption scopeOption)
{
ServiceConfig config = new ServiceConfig();
config.Transaction = (TransactionOption)scopeOption;
ServiceDomain.Enter(config);
ContextUtil.MyTransactionVote = TransactionVote.Abort;
}
public void Dispose()
{
if (m_Consistent == false && ContextUtil.IsInTransaction)
{
ContextUtil.MyTransactionVote = TransactionVote.Abort;
}
ServiceDomain.Leave();
m_Consistent = false;
}
}
TransactionScope事务
TransactionScope事务类,它可以使代码块成为事务性代码。并自动提升为分布式事务
优点:实现简单,同时能够自动提升为分布式事务
Demo:
/// <summary>
/// TransactionScope事务:可自动提升事务为完全分布式事务的轻型(本地)事务。
/// 使用时要保证MSDTC服务(控制分布事务)是开启的可以使用:net start msdtc命令开启服务;
/// </summary>
public void ADONetTran2()
{
SqlConnection conn = new SqlConnection"Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
SqlCommand cmd = new SqlCommand();
try
{
using (System.Transactions.TransactionScope ts = new TransactionScope())
{
cmd.CommandText = "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID";
cmd.CommandType = CommandType.Text;
cmd.Connection = conn;
conn.Open();
SqlParameter[] paras = new SqlParameter[]{
new SqlParameter ("@UpdateID",SqlDbType.Int,32),
new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)};
paras[0].Value = "2";
paras[1].Value = "Update Value12";
foreach (SqlParameter para in paras)
{
cmd.Parameters.Add(para);
}
cmd.ExecuteNonQuery();
cmd.CommandText = "insert into Region values(@InsertID,@InsertValue)";
cmd.CommandType = CommandType.Text;
paras = new SqlParameter[]{
new SqlParameter ("@InsertID",SqlDbType.Int ,32),
new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)};
paras[0].Value = "8";
paras[1].Value = "Insert Value";
cmd.Parameters.Clear();
foreach (SqlParameter para in paras)
{
cmd.Parameters.Add(para);
}
cmd.ExecuteNonQuery();
//提交事务
ts.Complete();
}
}
catch
{
throw;
}
finally
{
conn.Close();
}
}
COM+事务
在分布式应用程序中,往往要同时操作多个数据库,使用数据库事务就不能满足业务的要求了。在COM+中,提供完整的事务处理服务。很方便处理多个数据库上的事务。
Demo:
/// <summary>
/// COM+事务
/// </summary>
public void ComTran()
{
SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
SqlCommand cmd = new SqlCommand();
ServiceConfig sc = new ServiceConfig();
//指定事务类型
sc.Transaction = TransactionOption.Required;
//设置启动跟踪
sc.TrackingEnabled = true;
//创建一个上下文,该上下文的配置由作为 cfg 参数传递的 ServiceConfig 对象来指定。
//随后,客户端和服务器端的策略均被触发,如同发生了一个方法调用。
//接着,新的上下文被推至上下文堆栈,成为当前上下文
ServiceDomain.Enter(sc);
try
{
cmd.CommandText = "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID";
cmd.CommandType = CommandType.Text;
cmd.Connection = conn;
conn.Open();
SqlParameter[] paras = new SqlParameter[]{
new SqlParameter ("@UpdateID",SqlDbType.Int,32),
new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)};
paras[0].Value = "2";
paras[1].Value = "Update Value22";
foreach (SqlParameter para in paras)
{
cmd.Parameters.Add(para);
}
cmd.ExecuteNonQuery();
cmd.CommandText = "insert into Region values(@InsertID,@InsertValue)";
cmd.CommandType = CommandType.Text;
paras = new SqlParameter[]{
new SqlParameter ("@InsertID",SqlDbType.Int ,32),
new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)};
paras[0].Value = "9";
paras[1].Value = "Insert Value";
cmd.Parameters.Clear();
foreach (SqlParameter para in paras)
{
cmd.Parameters.Add(para);
}
cmd.ExecuteNonQuery();
//提交事务
ContextUtil.SetComplete();
}
catch
{
//回滚事务
ContextUtil.SetAbort();
throw;
}
finally
{
conn.Close();
//触发服务器端的策略,随后触发客户端的策略,如同一个方法调用正在返回。
//然后,当前上下文被弹出上下文堆栈,调用 Enter 时正在运行的上下文成为当前的上下文。
ServiceDomain.Leave();
}
}
在.net中还有些也能进行事务处理,如web Service中
需要特别补充的是:
如果你使用的是分布事务(TransactionScope事务和COM+事务),在默认情况下你是要重新配置安装SQL Server数据库服务器和访问数据库的客户端的.(如果没有配置运行会出现以下错误:该伙伴事务管理器已经禁止了它对远程/网络事务的支持。 (异常来自 HRESULT:0x8004D025)
)下面是MSDN上关于配置分布式事务的一段原话:
配置分布式事务
要启用分布式事务,可能需要通过网络启用 MS DTC,以便在使用应用了最新的 Service Pack 的较新操作系统(例如 Windows XP 或 Windows 2003)时使用分布式事务。如果启用了 Windows 防火墙(Windows XP Service Pack 2 的默认设置),必须允许 MS DTC 服务使用网络或打开 MS DTC 端口。
实际怎么配置呢,经过我的实际使用:大致如下:打开'控制面板'->'管理工具'->'组件服务',点开'组件服务'->'计算机'->'我的电脑',在'我的电脑'上右击属性,点'MSDTC',然后点'安全性配置'。作为数据库的服务器的配置如下:
而访问数据库的客户端的配置和服务器端的稍有些差别:
在设置完上面的还有使防火墙MS DTC 服务使用网络或打开 MS DTC 端口:运行netsh firewall set allowedprogram %windir%/system32/msdtc.exe MSDTC enable命令就可以了
- 解决大批量数据TransactionScope出错问题
- TransactionScope出错 (转)
- 转载自大牛的博文-解决大批量插入数据到数据库中的问题
- Java Web 解决POI导入大批量Excel2007数据报内存溢出问题
- 关于SXSSFWorkbook导出大批量数据的问题
- 解决大批量数据导出Excel产生内存溢出的方案
- 解决大批量数据导出Excel产生内存溢出的方案
- 解决大批量数据导出Excel产生内存溢出的方案
- 解决大批量数据导出Excel产生内存溢出的方案
- 解决大批量数据导出Excel产生内存溢出的方案
- 解决大批量数据导出Excel产生内存溢出的方案
- 解决大批量数据导出Excel产生内存溢出的方案
- TransactionScope()事务的问题
- Delphi用T-SQL大批量导入ACCESS数据注意问题
- C#大批量数据插入MySQL数据库的性能问题
- UDP大批量传输数据时的丢包问题优化
- KETTLE大批量提交数据时出现丢失问题
- ubuntu使用命令mongoimport插入大批量json数据到mongodb时,遇到转义字符出错解决办法
- 看Minix源码
- Linux学习计划
- wince6.0之S3C2416 128M DDR2 扩展
- 查询BOM死循环
- TNS错误
- 解决大批量数据TransactionScope出错问题
- 用JFreeChart绘制光滑曲线(二) 简单实现
- Eclipse使用axis2生成客户端调用时最后一步出现an error occurred while completing process -java.lang.reflect.InvocationTargetException
- django 查询对象
- hibernate中get和load得区别
- 怀念我的大学生活
- C/C++ 程序设计员应聘常见面试试题深入剖析
- 曾经苍海难为水,除却巫山不是云
- Struts第四天