postgresql 里面的事务,明明又错误为什么也执行了? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Fixedsys
V2EX    PostgreSQL

postgresql 里面的事务,明明又错误为什么也执行了?

  •  
  •   Fixedsys 2022 年 9 月 26 日 2837 次点击
    这是一个创建于 1213 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本人在初学 postgresql ,版本 14 ,关于事务,教程里说的额是如果有一个错误所有的命令都不会执行。

    但是下面的这个例子里面,原始表里并没有“T 恤衫”这个产品名,而是“T 恤”,所以将“T 恤衫”的价格上浮 1000 日元这个指令筛选不出来“T 恤衫”,我理解应该是错误的,但是 commit 之后,只有“运动 T 恤”的价格调了,“T 恤衫”上浮 1000 并没有实现。

    这个怎么解释呢?

    shop=# select * from product; product_id | product_name | product_type | sale_price | purchase_price | regist_date ------------+--------------+--------------+------------+----------------+------------- 0001 | T 恤 | 衣服 | 1000 | 500 | 2009-09-20 0002 | 打孔器 | 办公用品 | 500 | 320 | 2009-09-11 0003 | 运动 T 恤 | 衣服 | 4000 | 2800 | 0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-09-20 0005 | 高压锅 | 厨房用具 | 6800 | 5000 | 2009-01-15 0006 | 叉子 | 厨房用具 | 500 | | 2009-09-20 0007 | 擦菜板 | 厨房用具 | 880 | 790 | 2008-04-28 0008 | 圆珠笔 | 办公用品 | 100 | | 2009-11-11 (8 行记录) shop=# BEGIN TRANSACTION; BEGIN shop=*# -- 将运动 T 恤的销售单价降低 1000 日元 shop=*# UPDATE Product SET sale_price = sale_price - 1000 WHERE product_name = '运动 T 恤'; UPDATE 1 shop=*# -- 将 T 恤衫的销售单价上浮 1000 日元 shop=*# UPDATE Product SET sale_price = sale_price + 1000 WHERE product_name = 'T 恤衫'; UPDATE 0 shop=*# COMMIT; COMMIT shop=# select * from product; product_id | product_name | product_type | sale_price | purchase_price | regist_date ------------+--------------+--------------+------------+----------------+------------- 0001 | T 恤 | 衣服 | 1000 | 500 | 2009-09-20 0002 | 打孔器 | 办公用品 | 500 | 320 | 2009-09-11 0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-09-20 0005 | 高压锅 | 厨房用具 | 6800 | 5000 | 2009-01-15 0006 | 叉子 | 厨房用具 | 500 | | 2009-09-20 0007 | 擦菜板 | 厨房用具 | 880 | 790 | 2008-04-28 0008 | 圆珠笔 | 办公用品 | 100 | | 2009-11-11 0003 | 运动 T 恤 | 衣服 | 3000 | 2800 | (8 行记录) 
    7 条回复    2022-09-26 19:38:36 +08:00
    dayeye2006199
        1
    dayeye2006199  
       2022 年 9 月 26 日 via Android   2
    没毛病,两条语句都执行成功了,所以事物成功了。第一条更新 1 条记录,第二条更新 0 条记录,都执行成功。
    你问的应该是,怎么让更新 0 条记录的时候 update 语句失败,而不是成功。你可以在 update 之后加 returning id ,返回受到更新影响的行的主键。这时候 0 条记录更新的情况下,会直接失败。
    moen
        2
    moen  
       2022 年 9 月 26 日   1
    呃,你这个查询是顺利执行,只不过是无法匹配记录导致更新 0 行记录。没有顺利执行的那才是导致事务出错回滚
    felixcode
        3
    felixcode  
       2022 年 9 月 26 日 via Android   3
    SQL 是描述型语言,描述和操作的都是集合。
    所以匹配不上就是空集,而不是运行报错。
    PendingOni
        4
    PendingOni  
       2022 年 9 月 26 日
    @dayeye2006199 #1 正解,只要 SQL 事务操作中没有抛出异常就会一直执行,T 恤衫没有影响到任何一行
    nekoneko
        5
    nekoneko  
       2022 年 9 月 26 日
    你数据库哪有 'T 恤衫' 这个 product_name 啊
    nekoneko
        6
    nekoneko  
       2022 年 9 月 26 日
    # 1 正解
    Fixedsys
        7
    Fixedsys  
    OP
       2022 年 9 月 26 日
    好的,明白了,感谢各位大佬。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5121 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 09:28 PVG 17:28 LAX 01:28 JFK 04:28
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86