class Mutex
{
}
void lock(Mutex m)
{
}
void unlock(Mutex m)
{
}
void process()
{
}
void mutexDemo()
{
Mutex m = new Mutex();
lock(m); // 锁定该互斥量
scope(exit) unlock(m); // 在离开该域时解锁
process(); // 过程处理
}
// 多步事务时的回滚
class Transaction
{
this(Foo f, Bar b, Def d)
{
}
}
class Foo
{
}
class Bar
{
}
struct Def
{
}
Foo fooDo()
{
Foo f;
return f;
}
Bar barDo()
{
Bar b;
return b;
}
void undoFoo(Foo f)
{
}
void undoBar(Bar b)
{
}
Def doDef()
{
Def d;
return d;
}
Transaction transactionDemo()
{
Foo f;
Bar b;
Def d;
f = fooDo();
scope(failure) undoFoo(f);
b = barDo();
scope(failure) undoBar(b);
d = doDef();
return new Transaction(f, b, d);
}
// 状态管理
class State
{
bool _verbose; // =true表示输出信息;=false表示不输出
void foo()
{
auto verboseSaved = _verbose;
_verbose = false;
scope(exit) _verbose = verboseSaved; // 不管以何种方式(正常or异常)退出,都恢复之前保存的状态
// ...
}
}
/*
这里又另一个关于多步事务的例子,这次是一个电子邮件程序。发送一封电子邮件需要两个操作:
(1)完成 SMTP 发送操作。
(2)复制该电子邮件到“已发送(Sent)”文件夹,它对于 POP 是位于本地磁盘里面的,而对于 IMAP,则处于远端位置。
那些实际上没有被发送的信息不应该出现在“已发送(Sent)”里,而已经发送的信息必须出现在“已发送(Sent)”里。
操作(1)不是可恢复的,因为它是众所周知的分布计算问题。操作(2)是可恢复的,并且带有一定程度的可靠性(some degree of reliability)。因此我们将该工作分成三步:
(1)把信息复制到“已发送(Sent)”,同时把标题更改为 "[Sending] <Subject>"。这个操作要求确保在用户的 IMAP 账号里(或者本地磁盘)有一定的空间,以及连接存在并且有效等等。
(2)通过 SMTP 发送信息。
(3)如果发送失败,就从“已发送(Sent)”里删除该信息。 如果信息发送成功,就把标题由 "[Sending] <Subject>" 更改为 "<Subject>"。
这两个操作都有很高的成功性。如果该文件夹是本地的,成功的可能性非常高。如果文件夹是远程的,成功的可能性仍然比(2)要高很多,因为它并没有导致任意大数据的传送。
*/
class Msg
{
string _title; // char[]与string有什么区别?
int _ID;
string title()
{
return _title;
}
void setTitle(string title)
{
_title = title;
}
int ID()
{
return _ID;
}
}
class Mailer
{
void send(Msg msg)
{
{
string origTitle = msg.title();
scope(exit) msg.setTitle(origTitle);
msg.setTitle("[Sending] " ~ origTitle);
copy(msg, "Sent");
}
scope(success) setTitle(msg.ID(), "Sent", msg.title);
scope(failure) remove(msg.ID(), "Sent");
smtpSend(msg); // 最后做可靠性最低的部分
}
private:
void copy(Msg msg, string to)
{
}
void setTitle(int msgID, string from, string title)
{
}
void remove(int msgID, string from)
{
}
void smtpSend(Msg msg)
{
}
}
int main(string[] argv)
{
writeln("Hello D-World!");
mutexDemo();
transactionDemo();
auto s = new State();
s.foo();
auto msg = new Msg();
Mailer mailer = new Mailer();
mailer.send(msg);
getchar();
return 0;
}