?? exceptionhandling.htm
字號:
*write_it = *ins_it;
}
conn.CommitAll(); <span class="codeComment">// we assume commit and rollback must always succeed to avoid two-phase commit type logic</span>
}
catch(RootException &ex)
{
cout << ex << endl;
conn.RollbackAll();
}
cout << "Examples in view after attempted range insert:" << endl;
copy(view.begin(), view.end(), ostream_iterator<Example>(cout, "\n"));
vector<Example> read_from_DB_after;
copy(view.begin(), view.end(), back_inserter(read_from_DB_after));
cout << "Changes resulting from attempted range insert:" << endl;
TableDiff(cout, read_from_DB_before, read_from_DB_after);
}
</code></pre></FONT>
<FONT FACE="Courier New" SIZE=2><P>DTL does not provide built in support of range transactions for IndexedDBViews. (We thought about it, but the performance penalty was too high).Instead, you can get the effect of commit and rollback by copying your IndexedDBView's "initial" values to a backup IndexedDBView. To rollback, simply swap the backup IndexedDBView into the IndexedDBView that you made changes to. You will also have to call DBConnection::RollbackAll() to propagate the rollback to the database. This technique is used in the examples below.</FONT></P>
<FONT FACE="Courier New" SIZE=3>
<pre><code><span class="codeComment">// Range Transaction over a DBConnection: Insertion into a IndexedDBView </span>
const TIMESTAMP_STRUCT chrysalis = {2002, 4, 3, 0, 0, 0, 0};
const TIMESTAMP_STRUCT mikero = {2001, 11, 2, 0, 0, 0, 0};
const TIMESTAMP_STRUCT victory = {2001, 3, 10, 0, 0, 0, 0};
<span class="codeComment">// range transaction example for an indexed view</span>
void RangeIndexInsertExample()
{
DBConnection conn;
conn.Connect("UID=example;PWD=example;DSN=example;");
typedef DBView<Example> DBV;
DBV view("DB_EXAMPLE", DefaultBCA<Example>(),
"", DefaultBPA<DefaultParamObj<Example> >(), DefaultSelValidate<Example>(),
DefaultInsValidate<Example>(), conn);
view.set_io_handler(AlwaysThrowsHandler<Example>());
IndexedDBView<DBV> idxview(view,
"PrimaryIndex; STRING_VALUE; UNIQUE AlternateIndex; EXAMPLE_LONG, EXAMPLE_DATE",
BOUND);
cout << "Examples in view before attempted range insert:" << endl;
copy(idxview.begin(), idxview.end(), ostream_iterator<Example>(cout, "\n"));
vector<Example> read_from_DB_before;
copy(idxview.begin(), idxview.end(), back_inserter(read_from_DB_before));
<span class="codeComment">// examples that we want to insert into the DB ...
// we want an all or nothing on these guys!</span>
vector<Example> all_or_nothing_examples;
<span class="codeComment">// third element will fail to be inserted, should force rollback</span>
all_or_nothing_examples.push_back(Example(79, "FUBAR", 2.2, 99, mikero));
all_or_nothing_examples.push_back(Example(81, "All Messed Up", 21.09, 75, chrysalis));
all_or_nothing_examples.push_back(Example(85, "Bad Boy", -21.22, 11, victory));
all_or_nothing_examples.push_back(Example(99, "Good One", 77.99, 41, victory));
<span class="codeComment">// must write all the elements to succeed in the transaction
// else we rollback</span>
IndexedDBView<DBV> tmp(idxview); <span class="codeComment">// make copy so we can rollback to idxview on failure</span>
try {
for (vector<Example>::iterator ins_it = all_or_nothing_examples.begin();
ins_it != all_or_nothing_examples.end(); ins_it++)
{
idxview.insert(*ins_it); <span class="codeComment">// work with tmp</span>
}
conn.CommitAll(); <span class="codeComment">// we assume commit and rollback must always succeed to avoid two-phase commit type logic</span>
}
catch(RootException &ex)
{
cout << ex << endl;
idxview.swap(tmp); <span class="codeComment">// this will rollback to original results in memory</span>
conn.RollbackAll();
}
cout << "Examples in view after attempted range insert:" << endl;
copy(idxview.begin(), idxview.end(), ostream_iterator<Example>(cout, "\n"));
vector<Example> read_from_DB_after;
copy(idxview.begin(), idxview.end(), back_inserter(read_from_DB_after));
cout << "Changes resulting from attempted range insert:" << endl;
TableDiff(cout, read_from_DB_before, read_from_DB_after);
}
</code></pre>
<pre><code><span class="codeComment">// Range Transaction over a DBConnection: Updating in a IndexedDBView </span>
const TIMESTAMP_STRUCT chrysalis = {2002, 4, 3, 0, 0, 0, 0};
const TIMESTAMP_STRUCT mikero = {2001, 11, 2, 0, 0, 0, 0};
const TIMESTAMP_STRUCT victory = {2001, 3, 10, 0, 0, 0, 0};
<span class="codeComment">// range update</span>
void RangeIndexUpdateExample()
{
DBConnection conn;
conn.Connect("UID=example;PWD=example;DSN=example;");
typedef DBView<Example> DBV;
DBV view("DB_EXAMPLE", DefaultBCA<Example>(),
"", DefaultBPA<DefaultParamObj<Example> >(), DefaultSelValidate<Example>(),
DefaultInsValidate<Example>(), conn);
view.set_io_handler(AlwaysThrowsHandler<Example>());
IndexedDBView<DBV> idxview(view,
"PrimaryIndex; STRING_VALUE; UNIQUE AlternateIndex; EXAMPLE_LONG, EXAMPLE_DATE",
BOUND);
cout << "Examples in view before attempted range insert:" << endl;
copy(idxview.begin(), idxview.end(), ostream_iterator<Example>(cout, "\n"));
vector<Example> read_from_DB_before;
copy(idxview.begin(), idxview.end(), back_inserter(read_from_DB_before));
<span class="codeComment">// examples that we want to insert into the DB ...
// we want an all or nothing on these guys!
// string indicates key of element to replace, Example is object to replace the object
// to replace with</span>
map<string, Example> all_or_nothing_examples;
<span class="codeComment">// third element will fail to be updated, should force rollback</span>
all_or_nothing_examples["Bedazzled"] = Example(79, "FUBAR", 2.2, 99, mikero);
all_or_nothing_examples["Corwin"] = Example(81, "All Messed Up", 21.09, 75, chrysalis);
all_or_nothing_examples["Jordan"] = Example(85, "Bad Boy", -21.22, 11, victory);
all_or_nothing_examples["Mirror Image"] = Example(99, "Good One", 77.99, 41, victory);
<span class="codeComment">// must update all the elements to succeed in the transaction
// else we rollback</span>
IndexedDBView<DBV> tmp(idxview); <span class="codeComment">// make copy so we can rollback to idxview on failure</span>
<span class="codeComment">// march through vector and replace elements appropriately</span>
try {
map<string, Example>::iterator map_it;
for (map_it = all_or_nothing_examples.begin();
map_it != all_or_nothing_examples.end();
map_it++)
{
IndexedDBView<DBV>::iterator find_it = idxview.find((*map_it).first);
if (find_it != idxview.end())
idxview.replace(find_it, (*map_it).second);
}
conn.CommitAll(); <span class="codeComment">// we assume commit and rollback must always succeed to avoid two-phase commit type logic</span>
}
catch(RootException &ex)
{
cout << ex << endl;
idxview.swap(tmp); <span class="codeComment">// this will rollback to original results in memory</span>
conn.RollbackAll();
}
cout << "Examples in view after attempted range update:" << endl;
copy(idxview.begin(), idxview.end(), ostream_iterator<Example>(cout, "\n"));
vector<Example> read_from_DB_after;
copy(idxview.begin(), idxview.end(), back_inserter(read_from_DB_after));
cout << "Changes resulting from attempted range update:" << endl;
TableDiff(cout, read_from_DB_before, read_from_DB_after);
}
</code></pre>
</FONT>
And that's it! Congratulations you made it to the end of the document!
(We thought no-one ever would get here!)
<hr>
<p><a href="index.htm"><img src="dtl_home.gif" alt="[DTL Home]"
width="54" height="54"></a> <br>
</p>
<p>Copyright
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -