有這麼一個情境,在程式的service層的一個方法中有兩次資料庫訪問操作(分兩次調用不同dao的insert方法,一個dao只包含對一個資料表的操作方法),且都會改動資料。第一,往users表添加記錄,id是autoincrement(MySql資料庫)實現的;第二,向sms表插入記錄,且sms表有一欄位外鍵依賴users表的id。在該方法體添加了事務監控。
疑問1:我想在第二次的insert操作的sql語句(如insert into sms(userid, username,content) values((SELECT Auto_increment - 1 FROM information_schema.tables WHERE table_name='users' AND table_schema = DATABASE()),'username',
'content'));但是這樣做的前提是我在插入users的記錄後,要擷取的是剛剛插入的users記錄的id值,也就是在第二次insert前不會有其他對users表的修改操作。事務能做到這點嗎?
測試1:斷點達到第一次insert之後,第二次insert之前。於是在到達斷點時,我在mysql用戶端執行sql指令碼,這時看不到第一次insert插入的users記錄,但可以update已經存在的記錄。然後update所有記錄,此次指令碼執行會話會被掛起,直到程式中的事務結束,而如果長時間沒有停止事務,指令碼執行因會話逾時而停止,而在逾時之前停止事務,則sql指令碼繼續執行,並會影響新插入的users記錄。如果此時我向users表insert另一條記錄,也是可行的,只是autoincrement會在第一次insert的基礎上加1的,儘管現在還查不到第一次insert的記錄。
結果1:第一次insert執行後,第二次insert執行之前這段時間內,MySql仍會允許對users表的一些操作的,而這些操作可能會影響我第二次insert時所獲得的外索引值,所以上述第二次insert操作是不可行的。
疑問2:上述方法不可行,不過我可以在第二次insert時,使用select id from users where username = 'username',來獲得產生的id值,不過在前述中,通過用戶端是查不到事務未結束而已經新插入的記錄的,但是在同一個會話中我可以得到嗎?
測試2:按照設想修改代碼,運行結果顯示確確實實擷取到了users的新id值。