Atomic transtactions in non-transactional tables
I have 2 non-transactional tables. I want to perform an 'insert' on one and 'update' on another.
I want to do this atomically, both should go through or both should not.
How to achieve this for non-transactional tables? I开发者_StackOverflow中文版'm using MySql
Without the transactions mechanism, you need to protect the read and write code that will access the database.
Some pseudo-code to perform the write and read operations, in critical sections, protected via a semaphore:
Semaphore sem;
bool method write (data) {
lock(sem);
ok = do (insert data into table);
prevdata = do (select olddata from table2);
ok2 = do (update data into table2);
if (ok && !ok2) do (delete date from table);
else if (!ok && ok2) do (update olddata into table2);
unlock(sem);
return (ok && ok2);
}
datacontainer method read () {
lock (sem);
data = do (select data from table);
unlock(sem);
return data;
}
datacontainer method read2 () {
lock (sem);
data = do (select data from table2);
unlock(sem);
return data;
}
The synchronization can be optimized depending on your needs.
If you could use InnoDB, it is much simpler: in MySQL code
START TRANSACTION;
INSERT INTO table (...) VALUES (...);
UPDATE table2 SET data=... WHERE ...;
COMMIT;
Use locking:
LOCK TABLES t1, t2 WRITE;
...
UNLOCK TABLES;
NOTE: if any of the queries fail, you'll have to roll them back manually! So make sure you collect INSERT_ID()
s or some other ways to determine the rows you're inserting. (10x ring0)
If this happens too often in your application — you'll get awful performance.. In this case you'd better switch to InnoDB with its row-locking feature and transactions.
And make sure you ALWAYS either disconnect right after this operation or issue the UNLOCK TABLES
query! Otherwise (like forgetting to unlock/dying with an exception while using persistent connection to DB — you'll end up with a deadlock on these tables!)
精彩评论