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