最近開(kāi)發(fā)中遇到了使用mysql,多次開(kāi)啟事務(wù),出現(xiàn)了數(shù)據(jù)錯(cuò)亂問(wèn)題,偽代碼如下:
begin; #?操作1 begin; #?操作2 rollback;
執(zhí)行完后出現(xiàn)了操作1的數(shù)據(jù)真正寫(xiě)入,只有操作2的數(shù)據(jù)回滾了。在第一個(gè)事務(wù)沒(méi)有提交或回滾時(shí),再開(kāi)啟第二個(gè)事務(wù)時(shí),會(huì)自動(dòng)提交第一個(gè)事務(wù)。
這明顯不符合心理預(yù)期,而且也無(wú)法回滾一部分操作。那么問(wèn)題來(lái)了,MySQL 支不支持事務(wù)嵌套呢?
這個(gè)問(wèn)題很難準(zhǔn)確回答支持還是不支持!
首先,調(diào)用多次begin的寫(xiě)法,在MySQL里肯定是無(wú)法首先事務(wù)嵌套的。經(jīng)過(guò)群內(nèi)一位朋友的提醒,了解到MySQL中有一個(gè)叫savepoint和rollback to的語(yǔ)句。
示例代碼:
DROP?TABLE?IF?EXISTS?`test`; CREATE?TABLE?`test`?( ??`id`?int(10)?unsigned?NOT?NULL?AUTO_INCREMENT, ??`name`?varchar(255)?DEFAULT?NULL, ??PRIMARY?KEY?(`id`) )?ENGINE=InnoDB?AUTO_INCREMENT=1?DEFAULT?CHARSET=utf8; ? begin; ? insert?into?`test`(`name`)?values('111'); ? SAVEPOINT?p1; ? insert?into?`test`(`name`)?values('222'); ? ROLLBACK?TO?p1; ? commit;
最終執(zhí)行結(jié)果,test表中只有111這個(gè)數(shù)據(jù),實(shí)現(xiàn)了部分操作的回滾操作。同理也避免了多次開(kāi)啟事務(wù),導(dǎo)致前一個(gè)事務(wù)被提交的問(wèn)題。
可能savepoint和rollback to語(yǔ)句并不能稱之為事務(wù)嵌套,也不能說(shuō)MySQL是支持還是不支持事務(wù)嵌套。總之通過(guò)savepoint和rollback to,是可以用來(lái)達(dá)到一些事務(wù)嵌套特性的。