私は一般詰め込むを行うためのベース全体をチェックしを話す必要がありますコンソールアプリケーションを持っている...倍数接続 - マルチタスク
これを行うには、私はこのようなTasks
使用しています:
if (taskList.Count >= 2 * 5)
に気づいたかもしれませんが、問題は私の
Foo
と
Boo
方法が持っているということであるよう
10日一度を実行したい
static void Main(string[] args)
{
var dateStart = DateTime.Now.AddDays(-35);
var dateEnd = DateTime.Now;
var taskList = new List<Task>();
while (dateStart > dateEnd ? dateStart >= dateEnd : dateStart <= dateEnd)
{
var d = dateStart.Date;
var dispositivesBll = new DispositivesBll();
taskList.Add(Task.Run(() =>
{
dispositivesBll.Foo(d);
}).ContinueWith(
x => dispositivesBll.Dispose())
.ContinueWith(x => GC.Collect()));
var dispositivesBllNew = new DispositivesBll();
taskList.Add(Task.Run(() =>
{
dispositivesBllNew.Boo(d);
}).ContinueWith(
x =>
dispositivesBllNew.Dispose())
.ContinueWith(x => GC.Collect()));
if (taskList.Count >= 2 * 5)
{
Task.WaitAll(taskList.ToArray());
taskList.Clear();
}
dateStart = dateStart > dateEnd ? dateStart.AddDays(-1) : dateStart.AddDays(1);
}
Task.WaitAll(taskList.ToArray());
1つのOracle Databaseへの複数接続。
public class DispositivesBll : IDisposable
{
private readonly OracleDal _oracleDal = new OracleDal();
public void Foo(DateTime data)
{
var t1 = Task.Run(() =>
{
_listSuccess = _oracleDal.GetSuccessList();
});
var t2 =
Task.Run(() =>
{
listFailure = _oracleDal.GetFailureList();
});
t1.Wait();
t2.Wait();
foreach (var success in _listSuccess)
{
//Some logic to insert objects into a "mergeList"
}
if (mergeList.Any())
Task.Run(() => _oracleDal.MergeList(mergeList)).Wait();
}
public void Dispose()
{
if (_hash != null)
_hash.Clear();
_hash = null;
}
}
と私のマージ方法:
public void MergeList(List<MyObject> mergeList)
{
using (var conn = new OracleConnection(Connection.ConnectionString))
{
if (conn.State != ConnectionState.Open)
conn.Open();
using (var oCommand = conn.CreateCommand())
{
oCommand.CommandType = CommandType.Text;
oCommand.CommandText = string.Format(@"
MERGE INTO MyTable dgn
USING (select id from another_table where field = :xpe) d ON (TO_CHAR(dateHappen, 'DDMMYYYY') = {0} and id = :xId) WHEN MATCHED THEN
UPDATE SET OK = :xOk, dateHappen = SYSDATE
WHEN NOT MATCHED THEN
INSERT (fields....)
VALUES (values...)");
oCommand.BindByName = true;
oCommand.ArrayBindCount = mergeList.Count;
oCommand.Parameters.Add(":xId", OracleDbType.Int32,
mergeList.Select(c => Convert.ToInt32(c.Id)).ToArray(), ParameterDirection.Input);
oCommand.Parameters.Add(":xPe", OracleDbType.Varchar2,
mergeList.Select(c => Convert.ToString(c.Xpe)).ToArray(), ParameterDirection.Input);
oCommand.ExecuteNonQuery();
}
}
}
問題がある:各「日」のために、それはすべてのものを処理するために約2時間をtooks ...そして、我々はバックアップに毎日の計画を持っている私達のデータベース原因データベースは約10分停止します...それは私のプロセスでロックを引き起こすでしょう...
私は何をしますか?私はこのプロセスを手動で停止し、既に実行された日付を避けて再度起動します。しかし、私は20の接続を開いている場合、彼らはそのように滞在していたので...私は毎回それらのセッションを殺す必要があります...すべての接続を処分するよう強制する方法はありますか?だから、
MyTable
ID | STATE | DATE
によって構成さ50マイルの行が.... ...基本的に私は彼らの日程でそれらの状態を横断する必要がありました... それはデータベース上にある大きな遅延:
EDIT。 ..データベース全体のモデルをリファクタリングする必要があることはちょっと知られている問題です... ...
とにかく、処理時間にもかかわらず、力)接続を殺す、それは正常だろう...
アイデアは?
「1日2時間」の処理時間の大半はどこにありますか?それはデータベース側かアプリケーション側か?小規模なバッチで頻繁に実行した方が良いかもしれませんか?これは簡単な修正がある場合ではないかもしれません。プロセス全体の分析後に再設計が必要になる可能性があります。 – gmiley
「1日」のマージ処理は、実行に2時間近くかかることはありません。何百万行ものデータベース表であっても数分以内に実行する必要があります。 'MyTable'テーブルの行数と' another_table'の行数を大まかに知ることができます。また、手動でプロセスを強制終了して再起動するように設計されていることも気になります。また、適切なRMANバックアップを使用して、データベースをアーカイブ・ログ・モードにして、データベースのエクスポートを毎日行う必要はありません。 –
大多数はデータベース側にあります。1日4時間かかる同じ実装(タスクなし)がありますが、2時間でやり遂げましたが、実際にはすべての接続を制御する必要があります....私はいくつかの情報で質問を編集しました.... 'MyTable'と' another_table'は50マイル以上の行を持っています。そして、私は他の大きなテーブルと各レコードを結合する必要があります...時々、VARCHAR2(15)の値との結合が発生します....その非常に悪いモデル... –