`

oracle commit

阅读更多

http://blog.csdn.net/knowhow/archive/2008/01/13/2042266.aspx

 

那么,为什么COMMIT 的响应时间相当“平”,而不论事务大小呢?在数据库中执行COMMIT 之前,困难的工作都已经做了。我们已经修改了数据库中的数据,所以99.9% 的工作都已经完成。例如,已经发生了以下操作:

q          已经在SGA 中生成了undo 块。

q          已经在SGA 中生成了已修改数据块。

q          已经在SGA 中生成了对于前两项的缓存redo

q          取决于前三项的大小,以及这些工作花费的时间,前面的每个数据(或某些数据)可能已经刷新输出到磁盘。

q          已经得到了所需的全部锁。

执行COMMIT 时,余下的工作只是:

q          为事务生成一个SCN 。如果你还不熟悉SCN ,起码要知道,SCNOracle 使用的一种简单的计时机制,用于保证事务的顺序,并支持失败恢复。SCN 还用于保证数据库中的读一致性和检查点。可以把SCN 看作一个钟摆,每次有人COMMIT 时,SCN 都会增1.

q          LGWR 将所有余下的缓存重做日志条目写到磁盘,并把SCN 记录到在线重做日志文件中。这一步就是真正的COMMIT 。如果出现了这一步,即已经提交。事务条目会从V$TRANSACTION 中“删除”,这说明我们已经提交。

q          V$LOCK 中记录这我们的会话持有的锁,这些所都将被释放,而排队等待这些锁的每一个人都会被唤醒,可以继续完成他们的工作。

q          如果事务修改的某些块还在缓冲区缓存中,则会以一种快速的模式访问并“清理 。块清除(Block cleanout )是指清除存储在数据库块首部的与锁相关的信息。实质上讲,我们在清除块上的事务信息,这样下一个访问这个块的人就不用再这么做了。我们采用一种无需生成重做日志信息的方式来完成块清除,这样可以省去以后的大量工作(在下面的“块清除”一节中将更全面地讨论这个问题)。

可以看到,处理COMMIT 所要做的工作很少。其中耗时最长的操作要算LGWR 执行的活动(一般是这样),因为这些磁盘写是物理磁盘I/O 。不过,这里LGWR 花费的时间并不会太多,之所以能大幅减少这个操作的时间,原因是LGWR 一直在以连续的方式刷新输出重做日志缓冲区的内容。在你工作期间,LGWR 并非缓存这你做的所有工作;实际上,随着你的工作的进行,LGWR 会在后台增量式地刷新输出重做日志缓冲区的内容。这样做是为了避免COMMIT 等待很长时间来一次性刷新输出所有的redo

因此,即使我们有一个长时间运行的事务,但在提交之前,它生成的许多缓存重做日志已经刷新输出到磁盘了(而不是全部等到提交时才刷新输出)。这也有不好的一面,COMMIT 时,我们必须等待,直到尚未写出的所有缓存redo 都已经安全写到磁盘上才行。也就是说,对LGWR 的调用是一个同步(synchronous )调用。尽管LGWR 本身可以使用异步I/O 并行地写至日志文件,但是我们的事务会一直等待LGWR 完成所有写操作,并收到数据都已在磁盘上的确认才会返回。

前面我提高过,由于某种原因,我们用的是一个Java 程序而不是PL/SQL ,这个原因就是PL/SQL 提供了提交时优化(commit-time optimization )。我说过,LGWR 是一个同步调用,我们要等待它完成所有写操作。在Oracle  10g  Release 1 及以前版本中,除PL/SQL 以外的所有编程语言都是如此。PL/SQL 引擎不同,要认识到直到PL/SQL 例程完成之前,客户并不知道这个PL/SQL 例程中是否发生了COMMIT ,所以PL/SQL 引擎完成的是异步提交。它不会等待LGWR 完成;相反,PL/SQL 引擎会从COMMIT 调用立即返回。不过,等到PL/SQL 例程完成,我们从数据库返回客户时,PL/SQL 例程则要等待LGWR 完成所有尚未完成的COMMIT 。因此,如果在PL/SQL 中提交了100 次,然后返回客户,会发现由于存在这种优化,你只会等待LGWR 一次,而不是100 次。这是不是说可以在PL/SQL 中频繁地提交呢?这是一个很好或者不错的主意吗?不是,绝对不是,在PL/SQ; 中频繁地提交与在其他语言中这样做同样糟糕。指导原则是,应该在逻辑工作单元完成时才提交,而不要在此之前草率地提交。

注意        如果你在执行分布式事务或者以最大可能性模式执行Data GuardPL/SQL 中的这种提交时优化可能会被挂起。因为此时存在两个参与者,PL/SQL 必须等待提交确实完成后才能继续。

分享到:
评论

相关推荐

    Oracle Form中COMMIT的概述及使用技巧

    在Oracle Forms中,COMMIT是用于将表单(Form)中的数据变化同步到后台数据库的关键操作。这确保了用户在表单上所做的任何修改能够被持久化存储,从而保持数据库的完整性。以下是对COMMIT及相关操作的详细说明: 1....

    oracle执行update语句时卡住问题分析及解决办法

    这种只有update无法执行其他语句可以执行的其实是因为记录锁导致的,在oracle中,执行了update或者insert语句后,都会要求commit,如果不commit却强制关闭连接,oracle就会将这条提交的记录锁住。由于我的java程序...

    C#操作Oracle帮助类已经封装 本地无需安装oracle 内有说明文档

    6. `CommitTransaction()`: 提交当前事务。 7. `RollbackTransaction()`: 回滚当前事务。 除此之外,"使用说明.txt"文件很可能是提供了如何集成和使用OracleHelper类的详细步骤,包括但不限于如何添加引用、实例化...

    一段无需安装Oracle客户端即可访问Oracle数据库的delphi控件

    4. 事务处理:利用TOraSession的BeginTransaction、Commit和Rollback方法,可以进行数据库事务操作,确保数据的一致性。 5. 错误处理:ODAC提供了一套完整的错误处理机制,帮助开发者捕获和处理数据库操作中的异常。...

    Oracle 临时表用法

    ### Oracle 临时表用法详解 #### 一、背景与问题描述 在处理数据库操作时,经常遇到因数据量庞大而导致处理效率降低的问题。例如,某个报表中心的存储过程执行速度过慢,其中一个原因是该过程涉及到一个中间表,...

    delphi连接oracle(免装oracle客户端)测试

    4. **执行查询**:在代码中,可以通过TOraSession的BeginTransaction方法开始事务,然后调用TOraQuery的ExecSQL方法执行SQL,最后用CommitTransaction提交事务。 5. **异常处理**:在处理Oracle数据库操作时,应...

    查看登录oracle数据库用户记录.docx

    COMMIT; END; ``` 查看登录 Oracle 数据库用户记录 最后,需要使用以下 SQL 语句来查看登录 Oracle 数据库的用户记录: ```sql SELECT * FROM EVENT_LOG; ``` 这将显示用户的登录时间、用户名和登录 IP 地址等...

    python2.7_cx_oracle

    - 提交和回滚:使用`commit()`和`rollback()`方法来提交或回滚事务。 在实际开发中,还可能需要处理异常、绑定变量、使用存储过程、处理BLOB类型数据等高级功能。cx_Oracle 提供了丰富的API来满足这些需求。 总的...

    Oracle SQL高级编程

    3. 事务处理:深入理解如何使用Oracle的事务控制语句,如COMMIT、ROLLBACK以及SAVEPOINT,进行有效的事务管理。 4. 锁机制:了解和使用Oracle的锁定机制来处理并发事务,包括乐观锁定和悲观锁定。 5. 数据库触发器:...

    Sql语法转换为Oracle语法

    8. 事务处理:SQL Server使用 `BEGIN TRANSACTION`,`COMMIT` 和 `ROLLBACK`,Oracle也有对应的 `BEGIN`,`COMMIT` 和 `ROLLBACK`,但Oracle还提供了保存点(SAVEPOINT)功能。 9. 函数和内置操作:例如,SQL ...

    oracle 事务 回滚 存储过程

    在Oracle数据库中,事务的开始通常通过`BEGIN TRANSACTION`语句(或默认的隐式事务开始)启动,而结束则通过`COMMIT`或`ROLLBACK`语句完成。 ### Oracle存储过程 存储过程是在数据库中预编译的一组SQL语句,用于...

    最全的Oracle中文使用手册

    DML(数据操纵语言)用于插入、更新和删除数据,如`INSERT`、`UPDATE`、`DELETE`,以及`COMMIT`和`ROLLBACK`用于事务管理;DCL(数据控制语言)用于权限管理,如`GRANT`和`REVOKE`。 在查询方面,`SELECT`语句是...

    oracle 的instantclient18.5

    3. 管理事务:利用oci_trans_start和oci_trans_commit/rollback进行事务的开始和提交/回滚。 4. Java应用程序的JDBC连接:在Java代码中,通过Class.forName加载ojdbc8.jar中的驱动,然后使用DriverManager.get...

    Oracle批处理:使用C# 自带Oracle驱动一次执行多条Sql语句

    transaction.Commit(); } else { transaction.Rollback(); } ``` 通过以上步骤,我们便能在C#中使用Oracle自带驱动实现批处理,高效地执行多条SQL语句。这种方法不仅提高了性能,还能减少网络通信次数,对大型...

    oracle5.jar 和oracle6.jar驱动jar包

    Java的`Connection`对象提供了相关的事务控制方法,如`setAutoCommit()`和`commit()`。 3. **SQL注入**:为了防止SQL注入攻击,应使用预编译语句(PreparedStatement)代替直接字符串拼接SQL。 4. **异常处理**:...

    oracle 数据库用户被锁定在linux下操作

    5.提交修改,命令为:commit。 解决 SQLPlus 命令行工具中的错误 在使用 SQLPlus 命令行工具时,可能会出现一些错误,例如:“bash: sqlplus: command not found”或“Error 6 initializing SQL*Plus SP2-0667: ...

    Oracle JDBC驱动11.2.0.4

    JDBC驱动支持ACID(原子性、一致性、隔离性和持久性)事务特性,通过`Connection`对象的`setAutoCommit()`和`commit()`/`rollback()`方法控制事务。 6. **SQL执行**: 使用`Statement`、`PreparedStatement`和`...

    Oracle12C驱动包JDBC

    - **事务管理**:利用`java.sql.Connection`的`commit()`和`rollback()`方法控制事务。 - **连接池管理**:可以集成到应用服务器的连接池中,如Apache DBCP、C3P0或HikariCP,提高性能和资源利用率。 - **高级特性**...

Global site tag (gtag.js) - Google Analytics