近期突然想到,一道珠海笔试题,让你写atm机的逻辑,当时想多了,以为重点是让你写清楚其中的事务互斥关系,当时也忘记数据库是否会自动互斥,从而不会出现脏数据。所以就敲了个代码实践了下。
例子还是老例子.....卖票..不会卖出脏数据为好。
线程函数:
static DWORD WINAPI Ticket1(LPVOID lp)
{
while(1){
try{
CppSQLDB db;
//获取不是0则卖出
string s = "select * from Ticket";
db.ExectueQuery(s);
if(db.Eof())
return false;
int ticket;
db.GetIntValue("ticket",ticket);
if(ticket>0){
s = "update Ticket set ticket = ticket - 1";
if(db.ExecuteDML(s))
cout << "ticket 1 sale "<< tickets-- <<endl;
}else{
break;
}
}catch(_com_error& e){
cout << "error 1 "<< e.Description() << endl;
}
}
return 1;
}
当在多线程/进程的情况下,很容易想到,如果再某一时间,同时获取数据库得到票数为1,那么就可能卖出脏票,然而实际上通过sql中的触发器可以实现不会卖脏票,反之可以得出,数据库对一些更新的事务,会智能处理(应该是加锁),不会出现在某个时刻,同时执行了两次 ticket = ticket -1 而导致 ticket 只减少了一张,而卖出脏票。
CREATE trigger ticketTri on Ticket
for update
as
begin
IF EXISTS(select * from Deleted where ticket < 1)
begin
print ‘least‘;
rollback;
end
end