①一個未提交的事務(wù)所做的修改不能被其它事務(wù)所看到。只有當事務(wù)提交成功后,在該事務(wù)之后執(zhí)行的其它事務(wù)才可能看到該事務(wù)所做的改變。
②在該事務(wù)提交之前已經(jīng)執(zhí)行了一部分而另一部分在該事務(wù)提交后執(zhí)行的剩余部分同樣也看不到該事務(wù)做出的改變。這是另一個Oracle特性:讀一致和快照。
③在該事務(wù)提交同時進行的其它事務(wù)同樣也看不到該事務(wù)所做的改變。
2.語句級回滾
①當一個SQL語句在執(zhí)行期間因為發(fā)生的任何錯誤而中斷時,將產(chǎn)生一個“語句級回滾”。該回滾的后果就像這個SQL語句根本沒有執(zhí)行過一樣。
②注意回滾是發(fā)生在“執(zhí)行”階段的,如果是在SQL語句的解析階段因為語法問題而無法執(zhí)行。因為沒有產(chǎn)生任何影響而不會出現(xiàn)“回滾”。
3.事務(wù)控制的分割
如果一個事務(wù)中包含了DML語句和DDL語句,那么該事務(wù)會被分解成多個事務(wù)。首先在DDL之前的所有DML語句會被作為一個事務(wù)而一次性提交。然后Oracle會為這個DDL創(chuàng)建一個新的,單語句的事務(wù)。如果DDL語句執(zhí)行失敗了,那么DML事務(wù)依然成功。
4.不同情況下的事務(wù)控制
請注意:用戶從Oracle服務(wù)器斷開連接和用戶進程強行中斷的后果是不同的。
①前者典型的例子是Oracle服務(wù)器關(guān)閉或重啟,此時所有未提交事務(wù)會被提交。
②后者典型的例子用戶通過進程管理器強行kill掉進程,此時所有未提交事務(wù)所做的操作被回滾。
5.事務(wù)提交前要做的事情
Oracle提交一個事務(wù)之前,必須做以下幾件事情:
①記住數(shù)據(jù)被修改前是什么樣子的
②記住數(shù)據(jù)即將要被改成什么樣子
③記住redo log和undo log的關(guān)聯(lián)
④將SGA中已讀取到內(nèi)存的數(shù)據(jù)修改為新的值(此時并未真正保存到數(shù)據(jù)文件)
其中第一步是通過在undo表空間中記錄undo日志來完成的。第二步、第三步是通過向SGA中的redo日志緩沖區(qū)寫記錄來完成的。這樣當事務(wù)回滾時就可以從redo日志找到對應(yīng)的undo日志,從而找回之前的數(shù)據(jù)
★要特別注意的是:此時不一定會觸發(fā)DBWn進程。
★要特別注意的另一個地方是:第2步記錄事務(wù)操作的改變是內(nèi)存中進行的,還未寫到磁盤上的redo日志文件
6.事務(wù)提交時所做的事情
①記錄SCN值(System Change Number)
②將在線重做日志記錄(位于SGA的redo日志緩沖區(qū)中)持久化到redo日志文件
③Oracle釋放資源和鎖
④Oracle將事務(wù)標記為已結(jié)束
注意:只有在commit指令被發(fā)出后,才會將SGA中重做日志緩沖區(qū)的內(nèi)容刷新到磁盤的redo日志文件。在LGWR進程執(zhí)行前,重做日志一直存在于內(nèi)存中,也被稱為在線重做日志。
7.savepoint回滾和整個事務(wù)的回滾
注意當Oracle事務(wù)回滾到某個savepoint時,在savepoint之后的所有后續(xù)savepoint將失效。但此時Transaction還是活躍且可繼續(xù)的。這一點不同于整個事務(wù)的回滾。
8.自治事務(wù)
從傳統(tǒng)上來說,一個事務(wù)只有在完整執(zhí)行成功或回滾之后,才會進行下一個事務(wù)。而自治事務(wù)允許在一個事務(wù)中調(diào)用運行另一個事務(wù),被調(diào)用事務(wù)執(zhí)行完成后,調(diào)用事務(wù)繼續(xù)執(zhí)行之前未完成的操作直至事務(wù)結(jié)束
自治事務(wù)在被調(diào)用后,將和外圍事務(wù)完全獨立。彼此之間并不共享任何資源或者鎖,外圍事務(wù)所有未提交的改變對自治事務(wù)來說都是不可見。自治事務(wù)提交后外圍事務(wù)將可以看到改變。
-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。