1. sql的事務問題
如果沒有猜錯,樓主應該是在執行COMMIT TRANSACTION tran3 後,直接在當前的查詢界面查看的表裡的數據吧?對於當前會話,即使你沒有執行COMMIT,所有數據都會在當前的會話里發生變化,你可以不執行COMMIT TRANSACTION tran3,直接查看錶里的數據,你會看到即使沒有提交任何事物,表裡的數據還是發生變化了。如果你再打開一個查詢窗口,你會發現直接從testtran 表裡select數據是會一直等待的,因為其它會話(也就是開始你執行begin tran那個會話)有事務沒有提交,表是鎖定的。事務是用來保證多個會話之間不會應為事務不一致而產生臟數據。對同一會話,是看不出效果的。
2. 如何查出長時間沒有提交事務的sql執行語句
select s.sid,s.serial# ,ss.sql_text from v$session s ,v$sql ss where s.PREV_HASH_VALUE !=0 and s.SQL_HASH_VALUE=0 and s.PREV_HASH_VALUE=ss.hash_value and (ss.sql_text like '%insert%') order by s.sid,s.serial#;
會話長時間不提交,如果要對資料庫那張表做ddl維護操作,那就比較困難了.會話長時間不提交,通常是因為事務設計的不合理造成的. 注:把上面的語句改一下,也可以查詢update,與delete的sql語句
3. SQL 查詢能使用事務嘛合適嘛
事務,就是要麼全部執行,要麼全部不執行。
事務開始
插入表A一個欄位B (主鍵 int 標識 自動增)
<-- 假如這里意外發生了,那麼 最終 A 表不會多一條數據。
然後查詢出 這個表A的 欄位B的值
插入附屬表E 關聯欄位C (int )
<-- 假如這里意外發生了,那麼 最終 A 表 E 表 不會多數據。
結束事務
<-- 假如這里意外發生了,那麼 最終 A 表 E 表,還是有數據的。
==================================================
對於 Oracle 資料庫來說:
事務開始
插入表A一個欄位B (主鍵 int 標識 自動增)
-- 這個時候,只有你,能查詢到你剛才新增的那條記錄。
-- 你新增的,未提交的數據,其他人是看不到的。
然後查詢出 這個表A的 欄位B的值
插入附屬表E 關聯欄位C (int )
-- 這個時候,未提交, 你新增的 表A與表E的數據,只有你這個會話能看到
-- 別人看不到。
結束事務
-- 事務提交以後,別人
SELECT * FROM A
SELECT * FROM E
能夠看到你剛才插入的數據了。
============================
還是Oracle
事務是通過 一種叫 undo 的機制來處理的。
比如
事務開始
插入表A一個欄位B (主鍵 int 標識 自動增)
-- 將數據寫入到 表A的存儲區域
-- 同時記錄 undo 信息, 就是針對你的 INSERT INTO A ... 的SQL
-- undo 的 SQL 是 DELETE FROM A WHERE B=...
然後查詢出 這個表A的 欄位B的值
插入附屬表E 關聯欄位C (int )
-- 將數據寫入到 表E的存儲區域
-- 同時記錄 undo 信息, 就是針對你的 INSERT INTO E ... 的SQL
-- undo 的 SQL 是 DELETE FROM E WHERE C=...
-- 假如這個時候,伺服器重新啟動了
-- 那麼下次伺服器啟動的時候,將把沒有提交的事務 undo掉
-- 也就是執行前面的
-- DELETE FROM A WHERE B=...
-- DELETE FROM E WHERE C=...
結束事務
-- 這個時候,提交事務了,也就是 Commit 了。
-- 將 SCN ( System Change Number)遞增
-- 通過將 SCN 遞增,使得 別的用戶,可以訪問到你新增加的數據。
-- 前面所使用的 undo 空間,將騰出來,給別的用戶使用。
4. 如何判斷sql server目前有沒有事務在運行
-- 此語句用於查看最老的活動事務、未完成的分布式事務或復制事務的信息。
dbcc opentran
-- 通過動態管理視圖查看活動事務
select * from sys.dm_tran_active_transactions where transaction_stat=2