#include #include #include #include #include #include #include #include #include #include #include #include #define foreach BOOST_FOREACH using namespace std; using namespace boost; using namespace persistence; struct account{ //persistent object account(){} account(int account_nr) : account_nr(account_nr) , balance(0){} int account_nr; int balance; private: friend class boost::serialization::access; template void serialize(Archive &ar,unsigned int){ ar & account_nr; ar & balance; } }; struct bank{ //persistent object vector > accounts; int overall_balance() const{ int tmp=0; foreach(shared_ptr const &a,this->accounts){ tmp+=a->balance; } return tmp; } private: friend class boost::serialization::access; template void serialize(Archive &ar,unsigned int){ ar & accounts; } }; struct teller{ teller(db_ptr< ::bank> const &bank) : bank(bank){} void operator()(){ //thread start while(!exit){ try{ transaction tx; int amount=random() % 1000; int acc1=random() % bank->accounts.size(); int acc2=random() % bank->accounts.size(); bank->accounts[acc1]->balance-=amount; //withdraw bank->accounts[acc2]->balance+=amount; //deposit tx.commit(); }catch(isolation_exception &){ //this transaction conflicted with another transaction, all changes are undone. //normally, the exact same transaction should be restarted, but random //numbers are used in this case, so just continue; } } } db_ptr< ::bank> bank; static bool volatile exit; }; bool volatile teller::exit=false; void create_db(client &db,int nr_of_accounts){ transaction tx; db_ptr mybank(new bank); for(int c=0;c acc(new account(c)); mybank->accounts.push_back(acc); } db.root(mybank); tx.commit(); } int main(){ srand(time(0)); int nr_of_threads=10; int nr_of_accounts=200; filesystem_storage storage("mydb"); client db(storage); if(!db.root()) create_db(db,nr_of_accounts); db_ptr mybank=db.root(); cerr << "overall balance before: " << mybank->overall_balance() << endl; list > threads; for(int c=0;c(newthread)); } string wait; cin >> wait; threads.clear(); teller::exit=true; cin >> wait; cerr << "overall balance after: " << mybank->overall_balance() << endl; }