日期:2014-05-16  浏览次数:20653 次

oracle小记之事物(Procedure)

oracle的自定义事物(Procedure)一般是用DBMS_JOBS来调,也可以写个定时器调用。

以下是事物涉及的常用语法,自己看,不解释。。。

CREATE OR REPLACE PROCEDURE PRO_SYNCHRO_A_TO_B
/************创建时间XXXX-XX-XX*********************
*************把A系统的用户表A_USER数据同步到B系统的用户表B_USER中********************
*********************************/
IS
    --定义未同步A的A_USER表数据数量
    v_a_count NUMBER(15);

    /****异常定义*****/
    v_err_msg VARCHAR2(1024);
    -- 没有找需要到的数据异常
    not_a_user_data_ex EXCEPTION;
BEGIN
    --查询需要导出A_USER用户数量
    SELECT COUNT(1) INTO v_a_count FROM A_USER A WHERE
    NOT EXISTS(
        SELECT 1 FROM B_USER B WHERE B.ID = A.ID
    );
    IF v_a_count<=0 THEN
        --没有要导入的数据
        RAISE not_a_user_data_ex;
    END IF;
    --数据导入
    INSERT INTO B_USER(ID,USERNAME,PASSWORD)SELECT ID,USERNAME,PASSWORD FROM A_USER WHERE
    NOT EXISTS(
        SELECT 1 FROM B_USER B WHERE B.ID = A.ID    
        );
    --写入日志
    INSERT INTO T_LOG(EXEC_TIME,EXEC_PRC_NAME,ERROR_MSG,EXEC_ACTION,EXEC_STATUS)
    VALUES(SYSDATE,'PRO_SYNCHRO_A_TO_B',NULL,'同步A_USER数据#'||v_a_count||'#条','0');
    --提交数据
    COMMIT;
--异常处理
EXCEPTION
    WHEN not_a_user_data_ex THEN
        ROLLBACK;
         --写入日志
        INSERT INTO T_LOG(EXEC_TIME,EXEC_PRC_NAME,ERROR_MSG,EXEC_ACTION,EXEC_STATUS)
        VALUES(SYSDATE,'PRO_SYNCHRO_A_TO_B',NULL,'同步A_USER数据0条','0');
        --提交日志数据
        COMMIT;
    WHEN others THEN
        ROLLBACK;
        --写入日志
        v_err_msg:=SQLERRM;
        INSERT INTO T_LOG(EXEC_TIME,EXEC_PRC_NAME,ERROR_MSG,EXEC_ACTION,EXEC_STATUS)
        VALUES(SYSDATE,'PRO_SYNCHRO_A_TO_B',v_err_msg,'同步A_USER失败','1');
        --提交日志数据
        COMMIT;
END;

 

 

顺道引网友(http://www.cnblogs.com/ITtangtang/archive/2012/04/23/2466554.html)的例子说明一下事物的一致性和只读属性。

一、事务概念
事务用于保证数据的一致性,它由一组相关的dml语句组成,该组的dml(数据操作语言,增删改,没有查询)语句要么全部成功,要么全部失败。如:网上转账就是典型的要用事务来处理,用于保证数据的一致性。   

二、java程序中如何使用事务
在java操作数据库时,为了保证数据的一致性,比如账户操作(1)从一个账户中减掉10$(2)在另一个账户上加入10$,我们看看如何使用事务?

package junit.test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class TransationTest {

    public static void main(String[] args) {

        Connection conn = null;
        try {
            // 1.加载驱动
            Class.forName("oracle.jdbc.driver.OracleDriver");
            // 2.得到连接
            conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "SCOTT", "scott");
            Statement sm = conn.createStatement();
            // 从scott的sal中减去100
            sm.executeUpdate("update emp set sal=sal-100 where ename='SCOTT'");
            int i = 7 / 0; //报java.lang.ArithmeticException: / by zero异常
            // 给smith的sal加上100
            sm.executeUpdate("update emp set sal=sal+100 where ename='SMITH'");
            // 关闭打开的资源
            sm.close();
            conn.close();
        } catch (Exception e) {
            // 如果发生异常,就回滚
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }

    }

}


 

运行,会出现异常,查看数据库,SCOTT 的sal 减了100,但是SMITH 的sal 却不变,很可怕。。。我们怎样才能保证,这两个操作要么同时成功,要么同时失败呢?

package junit.test;

import java.sql.Connecti