事务相关问题

不久前,看了一道关于数据库的题。一个事务有2个语句,第一个语句执行成功,第二个语句因违反约束执行失败,请问提交之后会发生什么,大家在回答问题时,先别急于回帖,最好做个实验后,回帖顺便把实验结果贴出来。有可能结果和想象的不太一样哦。做完试验后,我在提出我的问题。
参与36

34同行回答

zsj2002zsj2002数据库管理员澳門大豐銀行
回复 27# zhenda     嗯加了DECLARE CONTINUE HANDLER FOR SQLEXCEPTION的话就可以说的通了。我也用JAVA模拟了我的想法写了一下。public class main {        private static Connection conn = null;      &nb...显示全部
回复 27# zhenda


    嗯加了DECLARE CONTINUE HANDLER FOR SQLEXCEPTION的话就可以说的通了。
我也用JAVA模拟了我的想法写了一下。

public class main {

        private static Connection conn = null;

        public static void main(String[] args) {
                // TODO Auto-generated method stub
                Statement st = null;
                try {
                        Class.forName("com.ibm.db2.jcc.DB2Driver");
                        conn = DriverManager.getConnection(
                                        "jdbc:db2://192.168.105.60:50001/db2pe", "db2inst1",
                                        "password");
                        //关闭自动提交(模拟+c)
                        conn.setAutoCommit(false);
                        //创建一个statment object
                        st = conn.createStatement();
                } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (ClassNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                //模拟正常插入
                try {
                st.executeUpdate("insert into t values(1)");
                } catch (SQLException e) {
                        System.out.println(e);
                }
                //模拟异常插入(输出错误)
                try {
                st.executeUpdate("insert into t values(\'d\')");
                } catch (SQLException e) {
                        System.out.println(e);
                }
                //模拟正常插入
                try {
                st.executeUpdate("insert into t values(1)");
                } catch (SQLException e) {
                        System.out.println(e);
                }
                //模拟提交
                try {
                        conn.commit();
                } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
        }

}

执行期间会报
com.ibm.db2.jcc.am.SqlDataException: DB2 SQL Error: SQLCODE=-420, SQLSTATE=22018, SQLERRMC=INTEGER, DRIVER=3.59.81
最后的结果也是两条正常的记录插入进去了(也是同一事物)。



虽然clp是用C写的,但是大概逻辑我想应该就是这样的吧。收起
银行 · 2015-03-10
浏览1440
zsj2002zsj2002数据库管理员澳門大豐銀行
回复 23# zhenda 但是有一个地方解释不通还想跟您探讨一下比如b2inst1@testing1:~> db2 +c "insert into t values(1)"DB20000I  The SQL command completed successfully.db2inst1@testing1:~> db2 +c "insert into t values('d')"DB21034E  The co...显示全部
回复 23# zhenda



但是有一个地方解释不通还想跟您探讨一下

比如

b2inst1@testing1:~> db2 +c "insert into t values(1)"
DB20000I  The SQL command completed successfully.

db2inst1@testing1:~> db2 +c "insert into t values('d')"
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL0420N  Invalid character found in a character string argument of the
function "INTEGER".  SQLSTATE=22018

db2inst1@testing1:~> db2 +c "insert into t values('1')"
DB20000I  The SQL command completed successfully.

db2inst1@testing1:~> db2 +c "select * from t"

I         
-----------
          1
          1

  2 record(s) selected.

db2inst1@testing1:~> db2 commit
DB20000I  The SQL command completed successfully.

db2inst1@testing1:~> db2 "select * from t"

I         
-----------
          1
          1

  2 record(s) selected.

db2inst1@testing1:~>


但是如果用procedure写的话

CREATE or replace PROCEDURE test
LANGUAGE SQL
snap:BEGIN not ATOMIC
insert into t values(1);
commit;
insert into t values('d');
commit;
insert into t values(1);
commit;
END snap @
--------------------------------------------
db2inst1@testing1:~> db2 "call test()"
SQL0420N  Invalid character found in a character string argument of the
function "INTEGER".  SQLSTATE=22018
db2inst1@testing1:~> db2 "select * from t"

I         
-----------
          1

  1 record(s) selected.

db2inst1@testing1:~>

procedure里面出错之后的语句都没有再执行,这个是正常的。

但是db2 +c 等于是不管是出错前的还是出错后的语句,只要是正常的都执行了。并且提交的时候都提交上去了。


我觉得这样应该解释得通

就是你在trancation中提交的语句如果有一句出错应该会整体回滚。

但是你用CLP提交的时候如果碰到了出错的语句应该是不会加入到事物中的,
比如你执行

db2 +c “insert into t values(1)”;
db2 +c “insert into t values(d)“;
db2 +c “insert into t values(1)”;


实际上db2的这个事物里面只执行了
db2 +c “insert into t values(1)”;
db2 +c “insert into t values(1)”;

中间那条已经报错返回了根本就没有给你加到事物中。


而你单独写一个trancation就不一样了
他会把三句都算到这个事物中,所以才会出现有一句错误就会整体回滚,或者对于not ATOMIC会把出错之前的都执行。

所以关于clp对于事物的定义是绝对符合的,只不过用clp执行的时候会把所有不成功的语句都过滤掉了而已。

通过写JAVA也能模拟出这种情况。收起
银行 · 2015-03-09
浏览1132
zsj2002zsj2002数据库管理员澳門大豐銀行
探讨的好深入,好厉害。学习新姿势显示全部
探讨的好深入,好厉害。学习新姿势收起
银行 · 2015-03-09
浏览558
niejiangshuiniejiangshui软件开发工程师屹通
你在clp内,执行2个db2 +c应该算2个事物了吧显示全部
你在clp内,执行2个db2 +c应该算2个事物了吧收起
银行 · 2015-03-03
浏览570
veslivesli系统架构师bank
《Database System Concepts》教材里对事务的定义:Collections of operations that form a single logical unit of work are calledtransactions. A database system must ensure proper execution of transactionsdespite failures—either the entire transaction exec...显示全部
《Database System Concepts》教材里对事务的定义:
Collections of operations that form a single logical unit of work are called
transactions. A database system must ensure proper execution of transactions
despite failures—either the entire transaction executes, or none of it does.收起
银行 · 2015-01-28
浏览798
gggeeqggggeeqg系统运维工程师中国银行
回复 2# atpeace331    从数据库的角度,每二条语句也算是正常的。显示全部
回复 2# atpeace331


   从数据库的角度,每二条语句也算是正常的。收起
银行 · 2015-01-28
浏览794
atpeace331atpeace331数据库管理员银行
刚刚试过了,第一条语句并没有因为第2条语句的执行失败而被回滚。我使用的是 SAMPLE 库中的 ACT 表。测试命令如下:            db2 +c "insert into act values (1,'test','fly') "          ...显示全部
刚刚试过了,第一条语句并没有因为第2条语句的执行失败而被回滚。我使用的是 SAMPLE 库中的 ACT 表。

测试命令如下:
            db2 +c "insert into act values (1,'test','fly') "
            命令执行成功

            db2 +c "insert into act values (2,'bbc','') "
            由于语句违反非空约束,执行失败
            db2  commit
            COMMIT 事务,感觉第一条语句的结果应该被回滚掉

            db2 " select * from act "
            结果两眼一坠,第一条语句的数据竟然已经插入到表中去了!!!

{:2_37:}收起
银行 · 2015-01-27
浏览802
zsj2002zsj2002数据库管理员澳門大豐銀行
回复 26# zhenda 我又根据我的想法画了个图片   显示全部
回复 26# zhenda


我又根据我的想法画了个图片

   

aaa.jpg

收起
银行 · 2015-01-27
浏览782

    提问者

    zhenda
    数据库管理员昆仑银行
    擅长领域: 数据库服务器云计算

    相关问题

    相关资料

    相关文章

    问题状态

  • 发布时间:2015-01-27
  • 关注会员:1 人
  • 问题浏览:25701
  • 最近回答:2015-03-23
  • X社区推广