mysql事务与锁以及kotlin的实际用法

mysql中的锁

首先需要介绍一下mysql的锁。一般我们使用InnoDB数据库引擎+行级锁,SQL为:SELECT * FROM table where id = 1 for update;for update为排外锁,锁了后其他session无法再加任何锁,需要释放之后才能操作。行级锁要求where中有唯一索引,如主键或者unique索引。这种锁允许其他session读,但是不可写。大部分情况下,我们不会使用lock tables TABLE write;,因为锁表的开支太大,锁行就足够了。

mysql的锁只在事务中生效。单独执行SELECT * FROM table where id = 1 for update;并不会加锁,需要先执行START TRANSACTION;或者set autocommit=0;后锁才生效,并在commit;或者rollback;后释放锁。否则,即使执行了for update语句,其他session也可以对这行数据随意操作。

mysql事务隔离级别

mysql事务隔离级别分为READ UNCOMMITTEDREAD COMMITTEDREPEATABLE READSERIALIZABLE
mysql默认的隔离级别为REPEATABLE READ,但是阿里云的数据库隔离级别为READ COMMITTED,可以从SELECT @@GLOBAL.transaction_isolation, @@GLOBAL.transaction_read_only;得到当前数据库实际隔离级别。

  • READ UNCOMMITTED 事务中任意改动都会直接生效,可被其他session查到。
  • READ COMMITTED 只有commit的操作才会被其他session查到。
  • REPEATABLE READ 只有commit的操作才会被其他session查到。但是在同一个事务处理中,读取的数据是一致的。如A session开始之后,B session修改数据A为数据B并commit,A session读到的数据依旧是A。
  • SERIALIZABLE 串行操作。在事务中,所有读取操作都会加共享锁,所以必须等写操作完成之后才能读。

从上往下,隔离程度越来越高。

例子如下:

--session 1
START TRANSACTION;
SELECT * FROM table where id = 1 for update;
-- 此时字段a是1
update table set a=100 where id=1;

--session 2
SELECT * FROM table where id = 1;
--不能加for update,否则会被锁。返回值a在READ UNCOMMITTED 下结果为100,其他情况下为1。

--session 1
SELECT * FROM table where id = 1 for update;
--同session可以随便重复锁。返回值a是100

--session 2
START TRANSACTION;
SELECT * FROM table where id = 1;
--READ UNCOMMITTED 下结果为100,其他情况下为1。

--session 1
COMMIT;

--session 2
SELECT * FROM table where id = 1;
--READ UNCOMMITTED和READ COMMITTED结果为100,其他为1,这也是REPEATABLE READ 重复读的含义所在。

kotlin中的具体实践

这里使用的是kotlin+jooq。注:@Transactional注解可以加在interface内的方法上。

    @Transactional
    override fun testRollBackWithT() {
        val res=dsl.selectFrom(Tables.T_TABLE)
                .where(Tables.T_TABLE.ID.eq(1))
                .forUpdate()
                .fetchOne()
        res.time=300
        res.update()
        throw Exception("test")
    }

必须开启Transactional注解,否则无效。此注解在这里的主要作用,是在调用的时候执行set autocommit=0;,调用成功后执行commit;,以及在失败后执行rollback;。不在Transactional作用域内进行的锁是无效的。

此注解本质是用cglib进行切片,处理事务初始化(即set autocommit=0;)等事项。因此如果在类的内部不带注解的方法调用带注解的方法,会导致注解无效。此外,如果嵌套注解,即带注解的A调用带注解的B,整个注解执行过程中任意出错都会导致整体回滚。不管嵌套多少层注解,事务初始化只会执行一次,commit也只会执行一次。任意一个带注解的方法执行失败,都会标注整个事务失败。例子如下:

    @Transactional
    fun test() {
        //此方法带@Transactional注解,不会抛异常
        updateWithout()
        try {
            //此方法带@Transactional注解,会抛异常
            updateWith()
        }catch (e:Exception){
        }
    }

在例子中,updateWith()带@Transactional注解并抛异常了,即使被上层捕获,依然会触发Transactional的回滚标记。虽然由于嵌套导致不会立即回滚,但是在上层运行结束触发commit的时候,会出现异常最终rollback,test方法内部所有数据库操作都会无效,如updateWithout()方法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352