c# – 使用datareader读取数百万个数据时,如何避免数据库连接丢失问题?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 使用datareader读取数百万个数据时,如何避免数据库连接丢失问题?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2608字,纯文字阅读大概需要4分钟。
内容图文
我有一个从数据库表中读取数据的类库.现在这个数据库表是客户端数据库,我的应用程序只有连接字符串和sql查询来打开连接,执行sql查询,读取数据并执行一些操作.
这个操作是什么,它有点复杂(基本上是业务规则).
现在,用户以特定格式提交sql查询,我的类库知道从sql查询结果中选择哪些列.
我不知道我的类库会处理的记录数.它也可能是100,200或数百万的数据.
目前,类库正在处理驻留在oracle上的9000万个数据.我正在使用SQLDATAREADER读取此数据.
现在的问题是避免内存异常我正在使用sql数据读取器读取数据但是逐个读取9千万个数据,然后对每个记录执行一些操作,连接将保持打开状态,目前我面临的问题是连接丢失:
ORA-03135: connection lost contact
1解决方案可能是读取块中的数据,但正如我所说,我不知道我可能正在处理的记录数量,并且SQL查询不在我手中,因为它是由我的类库提取的用户提交的.
有什么办法可以避免连接问题吗?
更新:
public class LongRunningTask : IDisposable
{
public void Start(DbConnection connection, string sql)
{
using (var cmd = connection.CreateCommand())
{
cmd.CommandText = sql;
cmd.CommandTimeout = 0;
connection.Open();
using (var dr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
//read 1 by 1 record and pass it to algorithm to do some complex processing
}
}
}
}
算法并不慢,这不是问题.主要问题是读取部分,如果当前来自ORACLE的数据为9千万,则速度很慢.
我已经测试了针对SQL SERVER的1亿个数据,我没有遇到过这个问题(虽然有时会出现传输层错误),尽管这个过程花费了很多时间.我只是在使用ORACLE时遇到了这个问题.
解决方法:
将数据读取器打开数小时并不是一个好主意.即使一切配置正确,线路上某处也可能出现瞬态错误(如您提到的传输层错误).
您可以在客户端代码中添加重试逻辑,以使其更加健壮.执行此操作的一种方法是跟踪上次处理的记录,并尝试在连接失败时重新连接并从该位置“恢复”.
private const int MAX_RETRY = 10;
private const int RETRY_INTERVAL_MS = 1000;
private string lastProcessedPosition = null;
public void Start(string connectionString, string sql)
{
var exceptions = new List<Exception>();
for (var i = 0; i < MAX_RETRY; i++)
{
try
{
if (Process(connString, sql, lastProcessedPosition)) return;
}
catch(Exception ex)
{
exceptions.Add(ex);
}
System.Threading.Thread.Sleep(RETRY_INTERVAL_MS);
}
throw new AggregateException(exceptions);
}
您的Process()方法将重新连接并跳过已处理的行:
public bool Process(string connString, string sql, string resumeFromPosition = null)
{
using ()// init your connection, command, reader
{
if (resumeFromPosition != null)
{
while (dr.Read() && dr.ToPositionString() != resumeFromPosition)
{
// skipping already processed records
}
}
while (dr.Read)
{
// Do your complex processing
// You can do this every N records if accuracy is not critical
lastProcessedPosition = dr.ToPositionString();
}
}
return true;
}
dr.ToPositionString()是一种扩展方法,您可以根据表模式创建一行唯一的行.
内容总结
以上是互联网集市为您收集整理的c# – 使用datareader读取数百万个数据时,如何避免数据库连接丢失问题?全部内容,希望文章能够帮你解决c# – 使用datareader读取数百万个数据时,如何避免数据库连接丢失问题?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。