V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
wangbenjun5
V2EX  ›  MySQL

到底什么情况下需要使用 MySQL 事务?

  •  1
     
  •   wangbenjun5 · 2021-09-01 18:42:24 +08:00 via Android · 7132 次点击
    这是一个创建于 1214 天前的主题,其中的信息可能已经有所发展或是发生改变。
    众所周知,MySQL 事务具有原子性,当你需要对对张表同时进行操作的时候,为了保证要么都成功,要么都失败,必须使用事务机制。

    但是仔细想想,举个例子 insert 操作,除非是 sql 语句写的有问题,正常情况下很难出错,除非是网络连接失败、数据库挂了、连接池满了等意外情况。这些都是极低概率事件。

    然而如果同时操作的表不在一个库就操蛋了……所以去 tm 的事务,听天由命吧,大不了表里面多几条废数据,用什么事务!我不用了
    第 1 条附言  ·  2021-09-01 19:33:00 +08:00
    纯属吐槽,我的意思是一些不太重要的业务可以不用,图个省事,特别是那种跨库的写表操作,丢了也就丢了,如果涉及订单、金额等重要业务确实使不得,分布式事务也得上
    第 2 条附言  ·  2021-09-01 21:25:38 +08:00
    各位大佬说的对,然而我就是不喜欢用事务,哈哈,哪天出 bug 找我我再修复 bug,这样工作量就上来了
    50 条回复    2021-09-03 17:22:08 +08:00
    AngryPanda
        1
    AngryPanda  
       2021-09-01 18:43:40 +08:00   ❤️ 26
    说的好!回去等通知。
    leonme
        2
    leonme  
       2021-09-01 18:48:43 +08:00 via iPhone
    正常情况下很难出错,这……举个例子,目前各种分布式共识算法,不就是解决非正常情况下的问题的吗? 事物本质上是简化应用层的开发工作
    hqs0417
        3
    hqs0417  
       2021-09-01 18:49:46 +08:00
    有些不一定是 SQL 语句的问题,可能是缺少必填字段,主键 /唯一键冲突。
    单库上使用事务可以降低系统复杂度。

    多库情况下就需要考虑最终一致了
    ch2
        4
    ch2  
       2021-09-01 18:51:55 +08:00
    我给你转 100W,转账失败了
    你的钱没多,我的钱扣了
    凭空消失 100W 你说事务有啥意义?
    Maboroshii
        5
    Maboroshii  
       2021-09-01 18:52:09 +08:00
    保证原子性... select update 一串操作的时候 。 当然 还要配置隔离级别这种东西。。不过我也基本没咋用过事务..
    falcon05
        6
    falcon05  
       2021-09-01 18:53:39 +08:00 via iPhone
    啊?
    zhaorunze
        7
    zhaorunze  
       2021-09-01 18:56:38 +08:00
    可以不用事务,你可以只创建一个表,其他所有场景都往这个表堆字段,行与行之间不需要共享,就不需要事务了。
    yianing
        8
    yianing  
       2021-09-01 18:58:17 +08:00 via Android
    账户的余额更改与流水创建必须在一个事务里面
    Yadomin
        9
    Yadomin  
       2021-09-01 18:59:01 +08:00
    “意外情况”,“极低概率” 就意味着不用管了?
    11232as
        10
    11232as  
       2021-09-01 19:02:18 +08:00   ❤️ 3
    事务不是个技术问题,事务是跟业务强相关得...
    SlipStupig
        11
    SlipStupig  
       2021-09-01 19:58:52 +08:00
    事务是用来保证数据库操作时的一致性和完整性啊,原子操作也是用来保证一致性啊,数据之间是有关联的一些你觉得不重要的数据可能会产生连锁反应。
    比如:订单库存量,在条件竞争的情况下,可能导致库存数量为负数,在一些特定促销场景下然后导致订单爆单,这个时候公司就遭受了损失,这部分损失你愿意承担嘛?
    Kilerd
        12
    Kilerd  
       2021-09-01 20:07:58 +08:00
    您说的对!
    sadfQED2
        13
    sadfQED2  
       2021-09-01 20:09:42 +08:00 via Android
    面试的时候需要使用事物
    love
        14
    love  
       2021-09-01 20:24:59 +08:00
    too young 了
    你以为就写数据库会出错?你的程序不会抛异常?抛了异常要不要回滚?就这么留着写了一半的数据集?
    sy20030260
        15
    sy20030260  
       2021-09-01 20:46:22 +08:00   ❤️ 1
    大部分垃圾代码就是「图个省事」带来的,写的人越省事,后续维护的人越蛋疼
    Senorsen
        16
    Senorsen  
       2021-09-01 21:22:54 +08:00
    1L + 10086 哈哈哈哈哈

    你操作一次出现异常(比如网络错误)的概率假设是万分之一,十万次操作出现异常的概率是多少?更多次操作呢?
    图省事没有事务了,除非用户量很少不到几十几百个,否则用户资源状态不一致,全乱了,导致不可用,怎么办?事后处理修数据怕是都难。
    seeker
        17
    seeker  
       2021-09-01 21:55:49 +08:00
    处理钱的时候。如果是个博客啥的,没了就没了把。
    billlee
        18
    billlee  
       2021-09-01 22:03:34 +08:00   ❤️ 1
    开事务还提升性能啊,innodb 不开事务那其实就是每条语句 auto-commit, 每行写入语句都要刷盘
    zhangxiaodao
        19
    zhangxiaodao  
       2021-09-01 23:10:59 +08:00
    大多数时候,事务是和锁一起使用用来控制并发的。非并发情况,用或不用,都是业务对编码的容忍度要求。

    但是,小同志,你这个『大不了多几条废数据』的思想不能有啊,写代码还是要严谨,坏习惯不能养。
    shiji
        20
    shiji  
       2021-09-01 23:24:56 +08:00
    哈哈,这就好比研究导弹干什么,搞一架客机+几组劳动人民从飞机往下一筐一筐扔手榴弹不就完了

    不过一个科技公司一旦高层技术人员都是这个思想,并对新来的 /严谨的人嗤之以鼻的话,基本离完蛋不差几年了。
    EscYezi
        21
    EscYezi  
       2021-09-02 01:42:28 +08:00 via iPhone
    “丢了就丢了”......希望出生产事故的时候楼主还能这么想
    yeqizhang
        22
    yeqizhang  
       2021-09-02 02:07:17 +08:00 via Android
    标题就起的很唬人,正文又描述的其它
    dayeye2006199
        23
    dayeye2006199  
       2021-09-02 02:19:06 +08:00
    我要是公司领导,我只想把 LZ 拖出去打屁屁
    felixcode
        24
    felixcode  
       2021-09-02 02:57:09 +08:00
    所以其它的可靠性设计在你这样的程序面前全都是个摆设,因为这样的程序在哪都是水桶的最短板。
    yogogo
        25
    yogogo  
       2021-09-02 07:44:32 +08:00
    多表操作的时候
    paranoiddemon
        26
    paranoiddemon  
       2021-09-02 08:03:19 +08:00 via Android
    加事务代码量很大?
    murmur
        27
    murmur  
       2021-09-02 08:43:11 +08:00
    这就是互联网思维,亲爱的用户我是你 X 爱用用不用拉倒,数据丢了就陪你点代金券就当无事发生
    msaionyc
        28
    msaionyc  
       2021-09-02 09:20:10 +08:00
    希望以后不会遇到你这种同事
    tabris17
        29
    tabris17  
       2021-09-02 09:34:01 +08:00 via iPhone   ❤️ 3
    再过几年,你回过头来看当年发的这个帖子,你内心会有多尴尬呀

    当然,那时候你可能也已经转行了
    pkoukk
        30
    pkoukk  
       2021-09-02 09:36:50 +08:00
    啧啧啧,我上大学的时候都问不出这种问题来。
    cbasil
        31
    cbasil  
       2021-09-02 09:49:38 +08:00
    例如商城里面优惠券使用,如果优惠券已经抵扣了,但是下单是因为用户账户问题下单失败,不用事务怎么处理优惠券还原的问题
    sujin190
        32
    sujin190  
       2021-09-02 10:33:16 +08:00
    恰恰多个操作不在同一个库才更需要事务,哥们,你搞反了
    banmuyutian
        33
    banmuyutian  
       2021-09-02 10:43:25 +08:00
    逆天
    realpg
        34
    realpg  
       2021-09-02 11:11:01 +08:00   ❤️ 1
    楼主,你要是入职哪个第三方支付一定告诉我啊,我多注册接
    heyjei
        35
    heyjei  
       2021-09-02 11:33:04 +08:00 via Android
    你们其实没看到楼主的问题在哪。

    楼主的问题是一个 insert 语句还要用 begin transaction, commit 包起来,觉得很麻烦。楼主不知道的是单独的 sql 语句,数据库执行的时候是默认开始并在语句结束后自动提交事务的。
    heyjei
        36
    heyjei  
       2021-09-02 11:40:42 +08:00 via Android
    而我们所说的事务,一般都是指有很多个 sql 语句一起执行的时候,需要用事务包起来,要么全部执行,要么全部不执行。

    在这里触发事务回滚的不一定是 SQL 写错了,或者磁盘故障,或者网络故障,更多的时候,我们触发回滚都业务上的逻辑,比如转账的时候,先 sql 减去了一个人的钱,然后通过另外一个 sql 语句发现对方账号锁了,转不进钱,于是这里只需要回滚事务就可以了,不需要重新执行 sql 一步步的恢复现场。


    这只是一个简单的例子,数据库的事务远远不止这些。
    heyjei
        37
    heyjei  
       2021-09-02 11:43:09 +08:00 via Android
    善用事务,可以极大的简化和优化你的业务逻辑代码
    kenvix
        38
    kenvix  
       2021-09-02 11:46:23 +08:00
    先不说别的,姑且问一句写过存储过程吗
    darkengine
        39
    darkengine  
       2021-09-02 12:44:27 +08:00
    是否需要提桶跑路 = 调用次数 * 故障发生概率 * 故障后果

    由此可知,不能因为“故障发生概率低”就不管
    Felldeadbird
        40
    Felldeadbird  
       2021-09-02 13:48:00 +08:00
    insert 语句也会出错啊。假定你某个 SQL 不稳定,导致一直 sleep 。这时候你 insert 就 wait 状态。你没事务的话,等 wait 结束后,他插入了数据。
    tairan2006
        41
    tairan2006  
       2021-09-02 14:21:02 +08:00
    、楼主脑子里没有并发的概念么
    sakasaka
        42
    sakasaka  
       2021-09-02 14:21:25 +08:00
    防止安全事故还有就是简化代码逻辑
    zxcslove
        43
    zxcslove  
       2021-09-02 14:23:14 +08:00
    就发泄情绪呗,谁还没个情绪了,哈哈哈
    chendy
        44
    chendy  
       2021-09-02 16:10:04 +08:00
    看了下楼主的历史发帖,细思极恐
    timethinker
        45
    timethinker  
       2021-09-02 17:31:29 +08:00
    事务改善了人们的生活,让我们可以用一个简单的编程模型来屏蔽底层的不确定性,这本身就是一个很伟大想法,但是要善用,很多情况下,问题不在于客观事物本身,而在于人。
    Chinsung
        46
    Chinsung  
       2021-09-02 17:42:29 +08:00
    首先开个事务对代码要求也不高吧,在 Spring 加个注解就完事了。分布式事务另说。
    其次就是,开不开事务对你实际执行的速度,影响应该没有想象中的大吧?
    在多条 sql 的情况下,使用很小的代价就可以获得原子性等等等特性,有啥麻烦的?
    goodboy95
        47
    goodboy95  
       2021-09-02 20:02:53 +08:00
    我的系统,有些功能前前后后要改十几次数据,没事务会死的
    ninglg
        48
    ninglg  
       2021-09-02 23:33:57 +08:00
    如果只需要考虑正常情况,那程序的世界就太美好了
    zoyua
        49
    zoyua  
       2021-09-03 10:03:46 +08:00
    呃,事务还是很重要的
    xipushi
        50
    xipushi  
       2021-09-03 17:22:08 +08:00
    我碰到 java 代码里面, 基本不需要特别关心事务提交。

    同事写了个事务+异步的代码,查了我大半天

    ```
    @Transactional
    methodA(){
    Object a = reponsitory.save();
    async methodB(a.id) //异步调用
    .....
    //若干操作
    }


    methodB(id){
    reponsitory.findById(id) // 这里偶尔查不到数据
    }
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2690 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 12:17 · PVG 20:17 · LAX 04:17 · JFK 07:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.