-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
830 lines (567 loc) · 39.7 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<title>NOOB - 许炎的个人博客</title>
<meta name="keywords" content="github, 技术博客, web开发, fontend">
<meta name="description" content="许炎的个人博客">
<meta property="og:type" content="website">
<meta property="og:title" content="NOOB">
<meta property="og:url" content="https://blog.staynoob.cn/index.html">
<meta property="og:site_name" content="NOOB">
<meta property="og:description" content="许炎的个人博客">
<meta property="og:locale">
<meta property="article:author" content="noob9527">
<meta property="article:tag" content="github, 技术博客, web开发, fontend">
<meta name="twitter:card" content="summary">
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico " />
<link rel="Bookmark" type="image/x-icon" href="/favicon.ico " />
<link rel="icon" type="image/x-icon" href="/favicon.ico " />
<meta name="google-site-verification" content="9GCG5tynfuvxF_9_xHvo8tvc7CqHeqKMZQqda25rDPs" />
<meta name="baidu-site-verification" content="IVBrfkvovZ" />
<link rel="alternative" href="/atom.xml" title="NOOB" type="application/atom+xml">
<script src="/vendors/jquery/jquery.js"></script>
<script src="/vendors/bootstrap/js/bootstrap.js"></script>
<script src="/js/script.js"></script>
<link rel="stylesheet" href="/vendors/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="/css/style.css">
<script type="text/javascript" id="hexo.configuration">
var CONFIG = {
search: {
path: '/search.xml'
}
};
</script>
<meta name="generator" content="Hexo 6.3.0"></head>
<body>
<header id="site-nav">
<div id="banner"></div>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- social link-->
<div class="social-link">
<ul class="nav navbar-nav navbar-left">
<li><a href="https://github.com/noob9527" target="_blank">
<i class="fa fa-2x fa-github"></i>
</a></li>
<li><a href="http://weibo.com/p/1005052678297054" target="_blank">
<i class="fa fa-2x fa-weibo"></i>
</a></li>
<li><a href="/atom.xml" rel="alternate">
<i class="fa fa-2x fa-rss"></i>
</a></li>
</ul>
</div>
<div class="navbar-header">
<!--toggle button-->
<button class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#navbar-link" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!--brand-->
<a href="/" class="navbar-brand">
<span>NOOB</span>
</a>
</div>
<!--link-->
<div class="collapse navbar-collapse" id="navbar-link">
<ul class="nav navbar-nav navbar-right">
<li>
<a href="/" rel="section">
<i class="fa fa-home fa-fw"></i>
首页
</a>
</li>
<li>
<a href="/archives" rel="section">
<i class="fa fa-archive fa-fw"></i>
归档
</a>
</li>
<li>
<a href="/about" rel="section">
<i class="fa fa-user fa-fw"></i>
关于
</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="site-content container-fluid">
<div class="row">
<div class="col-md-9">
<main>
<article id="post-notes-on-high-performance-mysql"
class="post post-type-post" itemscope itemprop="blogPost">
<div class="post-inner">
<!-- title -->
<header class="post-header">
<h1 itemprop="name">
<a href="/post/2024/06/notes-on-high-performance-mysql/">Notes on High Performance MySQL</a>
</h1>
</header>
<!-- meta data -->
<div class="post-meta">
<span class="post-date">
<span class="post-meta-item-icon">
<i class="fa fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time itemprop="datePublished" datetime="2024-06-29T18:15:31+08:00"
content="2024-06-29">
2024-06-29
</time>
</span>
<span class="post-category">
|
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="https://schema.org/Thing">
<a class="article-category-link" href="/categories/Backend/">Backend</a>
</span>
</span>
</div>
<!-- gallery-->
<!-- entry -->
<div class="post-entry" itemprop="postBody">
<!--摘录-->
<blockquote>
<p>Notes on <a target="_blank" rel="noopener" href="https://www.amazon.com/High-Performance-MySQL-Optimization-Replication/dp/1449314287/ref=sr_1_5?keywords=mysql&qid=1560589416&s=books&sr=1-5">High Performance MySQL</a>, for future reference.</p>
</blockquote>
<h3 id="Chapter-4-Optimizing-Schema-and-Data-Types"><a href="#Chapter-4-Optimizing-Schema-and-Data-Types" class="headerlink" title="Chapter 4: Optimizing Schema and Data Types"></a>Chapter 4: Optimizing Schema and Data Types</h3><h4 id="Choosing-Identifiers"><a href="#Choosing-Identifiers" class="headerlink" title="Choosing Identifiers"></a>Choosing Identifiers</h4><blockquote>
<p>Integers are usually the best choice of identifiers. Avoid string types for identifiers if possible, because they take up a lot of space and are generally slower than integer types. You should also be very careful with completely “random” strings, such as those produced by MD5() , SHA1() , or UUID().</p>
</blockquote>
<!--阅读全文-->
<p class="post-more-link">
<a href="/post/2024/06/notes-on-high-performance-mysql/#more">阅读全文</a>
</p>
</div>
<footer class="post-footer">
</footer>
</div>
</article>
<article id="post-exploration-vs-exploitation"
class="post post-type-post" itemscope itemprop="blogPost">
<div class="post-inner">
<!-- title -->
<header class="post-header">
<h1 itemprop="name">
<a href="/post/2024/06/exploration-vs-exploitation/">Exploration vs Exploitation</a>
</h1>
</header>
<!-- meta data -->
<div class="post-meta">
<span class="post-date">
<span class="post-meta-item-icon">
<i class="fa fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time itemprop="datePublished" datetime="2024-06-29T17:53:53+08:00"
content="2024-06-29">
2024-06-29
</time>
</span>
<span class="post-category">
|
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="https://schema.org/Thing">
<a class="article-category-link" href="/categories/Diary/">Diary</a>
</span>
</span>
</div>
<!-- gallery-->
<!-- entry -->
<div class="post-entry" itemprop="postBody">
<!--文章内容-->
<div class="post-content"><blockquote>
<p>A short note on <a target="_blank" rel="noopener" href="https://youtu.be/FgzM3zpZ55o?si=UdTA9MaP9EalwMu5&t=3311">Standford CS234 Reinforcement Learning 2019 Lecture1</a><br>How should an RL agent balance its action?</p>
<ul>
<li>Exploration: trying new things that might enable the agent to make better decisions in the future</li>
<li>Exploitation: choosing actions that are expected to yield good reward given the past experience</li>
</ul>
<p>Often there may be an exploration-exploitation tradeoff, we may have to sacrifice reward in order to explore and learn about better policy.</p>
</blockquote>
<p>To make the idea concrete, if you go to a restaurant, they have several different dishes, you want to optimize at the best dish, the best strategy is actually depends on how long you will spend near that restaurant. If you are going to live there for a long time, the best strategy is try them all, instead, when you go to the restaurant last time, you should order the known best dish.<br>The underlying idea is fairly simple, when it applys to human lives, it means you should try different things while you are young, and stick to whatever interests you when you gets old.<br>It also suggests, "Treat everyday as if it's your last day" is actually a terrible strategy. Because if it is your last day, you should always choose to do whatever gives you the maximum pleasure, but if you have future, you should take more time for "exploration".</p>
</div>
</div>
<footer class="post-footer">
</footer>
</div>
</article>
<article id="post-why-i-think-kotlin-is-preferable-to-java"
class="post post-type-post" itemscope itemprop="blogPost">
<div class="post-inner">
<!-- title -->
<header class="post-header">
<h1 itemprop="name">
<a href="/post/2019/10/why-i-think-kotlin-is-preferable-to-java/">Why I think Kotlin is preferable to Java</a>
</h1>
</header>
<!-- meta data -->
<div class="post-meta">
<span class="post-date">
<span class="post-meta-item-icon">
<i class="fa fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time itemprop="datePublished" datetime="2019-10-26T09:28:06+08:00"
content="2019-10-26">
2019-10-26
</time>
</span>
<span class="post-category">
|
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="https://schema.org/Thing">
<a class="article-category-link" href="/categories/Programming-Language/">Programming Language</a>
</span>
</span>
</div>
<!-- gallery-->
<div class="post-gallery">
<div class="post-gallery-photos">
<!--<a class="post-gallery-img fancybox" href="/img/why-i-think-kotlin-is-preferable-to-java.jpg" rel="gallery_cly05xlzo002qbuey1zbgfey9">-->
<img src="/img/why-i-think-kotlin-is-preferable-to-java.jpg" itemprop="image">
<!--</a>-->
</div>
</div>
<!-- entry -->
<div class="post-entry" itemprop="postBody">
<!--摘录-->
<blockquote>
<p>Although I'm quite impressed by Rust language recently, Kotlin is still my favorite language. In this post, I will share the major reasons which convinced me to leave Java two years ago. It won't cover every bright side of Kotlin language, but will be enough to make my point.</p>
</blockquote>
<p>TL:DR</p>
<h3 id="Java-the-Good-Parts-and-the-Bad-Parts"><a href="#Java-the-Good-Parts-and-the-Bad-Parts" class="headerlink" title="Java the Good Parts and the Bad Parts"></a>Java the Good Parts and the Bad Parts</h3><p>If you ever asked me if Java is a good programming language, I would definitely say yes. Compare to languages such as C++, VB, Javascript. Writing code in Java is much more pleasant. More specifically, its virtue including but not limited to:</p>
<ul>
<li>Cross Platform</li>
<li>Statically Typed</li>
<li>Automatic Memory Management</li>
<li>Open Community</li>
<li>(After all, When I could not make a living by writing some fancy languages. It was Java gave me a job so that I could complain it all day.)</li>
</ul>
<p>Anyway, just like other elder languages, Java has made many design mistakes, I won't dive into the language design topic here, as I'm not a specialist in programming language (or any other) field. I just want to share some issues that do bother me, from a mediocre programmer's perspective, then see how they are solved in Kotlin.</p>
<!--阅读全文-->
<p class="post-more-link">
<a href="/post/2019/10/why-i-think-kotlin-is-preferable-to-java/#more">阅读全文</a>
</p>
</div>
<footer class="post-footer">
</footer>
</div>
</article>
<article id="post-when-soft-delete-meets-unique-index"
class="post post-type-post" itemscope itemprop="blogPost">
<div class="post-inner">
<!-- title -->
<header class="post-header">
<h1 itemprop="name">
<a href="/post/2019/05/when-soft-delete-meets-unique-index/">When "Soft Delete" Meets "Unique Index"</a>
</h1>
</header>
<!-- meta data -->
<div class="post-meta">
<span class="post-date">
<span class="post-meta-item-icon">
<i class="fa fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time itemprop="datePublished" datetime="2019-05-21T00:17:16+08:00"
content="2019-05-21">
2019-05-21
</time>
</span>
<span class="post-category">
|
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="https://schema.org/Thing">
<a class="article-category-link" href="/categories/Backend/">Backend</a>
</span>
</span>
</div>
<!-- gallery-->
<div class="post-gallery">
<div class="post-gallery-photos">
<!--<a class="post-gallery-img fancybox" href="/img/when-soft-delete-meets-unique-index.jpg" rel="gallery_cly05xlzn002mbuey2esed83j">-->
<img src="/img/when-soft-delete-meets-unique-index.jpg" itemprop="image">
<!--</a>-->
</div>
</div>
<!-- entry -->
<div class="post-entry" itemprop="postBody">
<!--摘录-->
<blockquote>
<p>Do some casually writing to practice my English.</p>
</blockquote>
<p>Recently, I was asked to enable soft delete for all the tables I created, it sounds like a breeze, as an experienced noob, I "finished" it immediately without even think about it. This is how I did, add a boolean column named "deleted" for each table, then replace every unique index to include the "deleted" column, done! Anyway, It turns out I was too naive.</p>
<h3 id="What-39-s-wrong-with-my-naive-solution"><a href="#What-39-s-wrong-with-my-naive-solution" class="headerlink" title="What's wrong with my naive solution?"></a>What's wrong with my naive solution?</h3><p>Imagine that we have a user table:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> `<span class="keyword">user</span>` (</span><br><span class="line"> `id` <span class="type">int</span>(<span class="number">11</span>) <span class="keyword">NOT</span> <span class="keyword">NULL</span> AUTO_INCREMENT,</span><br><span class="line"> `username` <span class="type">varchar</span>(<span class="number">50</span>) <span class="keyword">NOT</span> <span class="keyword">NULL</span>,</span><br><span class="line"> `deleted` tinyint(<span class="number">1</span>) <span class="keyword">NOT</span> <span class="keyword">NULL</span> <span class="keyword">DEFAULT</span> <span class="number">0</span>,</span><br><span class="line"> <span class="keyword">PRIMARY</span> KEY (`id`),</span><br><span class="line"> <span class="keyword">UNIQUE</span> KEY `uq_user` (`username`,`deleted`)</span><br><span class="line">)</span><br></pre></td></tr></table></figure><br>Whenever we need to "soft delete" a user, we set the value of the "deleted" column to 1, what could possibly go wrong?<br>Now, let's say we have a user "John Snow", we deleted the corresponding record with the following command after he was killed in GOT season 5.<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">update</span> <span class="keyword">user</span> <span class="keyword">set</span> deleted <span class="operator">=</span> <span class="number">1</span> <span class="keyword">where</span> id <span class="operator">=</span> #{id};</span><br></pre></td></tr></table></figure><br>then we insert it again after they bring him back in season 6.<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">insert</span> <span class="keyword">user</span>(username) <span class="keyword">values</span> ("John Snow");</span><br></pre></td></tr></table></figure><br>Everything works smoothly so far, except that we won't able to delete him again. this time <code>update user set deleted = 1 where id = #{id};</code> will raise a duplicate records error, that is exactly what the unique constraint does, but apparently, it violates our intention.<br>The problem is, we only want the username to be unique if the user is active, we don't care if there are multiple deleted user share a username. In other words, we only want a partially unique constraint which restricts the active user.</p>
<!--阅读全文-->
<p class="post-more-link">
<a href="/post/2019/05/when-soft-delete-meets-unique-index/#more">阅读全文</a>
</p>
</div>
<footer class="post-footer">
</footer>
</div>
</article>
<article id="post-the-good-old-transaction"
class="post post-type-post" itemscope itemprop="blogPost">
<div class="post-inner">
<!-- title -->
<header class="post-header">
<h1 itemprop="name">
<a href="/post/2019/05/the-good-old-transaction/">The Good Old Transaction</a>
</h1>
</header>
<!-- meta data -->
<div class="post-meta">
<span class="post-date">
<span class="post-meta-item-icon">
<i class="fa fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time itemprop="datePublished" datetime="2019-05-07T23:22:54+08:00"
content="2019-05-07">
2019-05-07
</time>
</span>
<span class="post-category">
|
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="https://schema.org/Thing">
<a class="article-category-link" href="/categories/Backend/">Backend</a>
</span>
</span>
</div>
<!-- gallery-->
<div class="post-gallery">
<div class="post-gallery-photos">
<!--<a class="post-gallery-img fancybox" href="/img/the-good-old-transaction.jpg" rel="gallery_cly05xlzm002jbuey2gyp48ks">-->
<img src="/img/the-good-old-transaction.jpg" itemprop="image">
<!--</a>-->
</div>
</div>
<!-- entry -->
<div class="post-entry" itemprop="postBody">
<!--摘录-->
<blockquote>
<p>随便写写跟事务相关的笔记</p>
</blockquote>
<h2 id="ACID"><a href="#ACID" class="headerlink" title="ACID"></a>ACID</h2><h3 id="原子性-Atomicity"><a href="#原子性-Atomicity" class="headerlink" title="原子性(Atomicity)"></a>原子性(Atomicity)</h3><p>这里的原子性含义与多线程编程中的原子性有一些细微的区别,在多线程语境中,如果一个方法满足原子性,则其它线程无法看到该方法执行的中间状态,但它并不保证该方法中的语句全生效或全不生效(All or Nothing)。相反,ACID 中的原子性保证 All or Nothing,但其并不保证其它事务是否能看到该事务执行的中间状态,在 ACID 中,该属性由隔离性(Isolation)来保证。考虑下面这段程序<br><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> counter: <span class="built_in">Int</span> = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Synchronized</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">increase</span><span class="params">()</span></span> {</span><br><span class="line"> counter++;</span><br><span class="line"> <span class="keyword">if</span> (ThreadLocalRandom.current().nextBoolean())</span><br><span class="line"> <span class="keyword">throw</span> Exception(<span class="string">"Oops!"</span>)</span><br><span class="line"> counter++;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Synchronized</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">printCurrent</span><span class="params">()</span></span> {</span><br><span class="line"> println(counter);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><br>这里 @Synchronized 保证 increase 方法是符合原子性的,这意味着,如果没有异常出现,则 printCurrent 方法不可能打印出一个奇数。但如果出现异常,counter 的第一次自增并不会回滚,也就是说这次 increase 调用只将 counter 自增1。与其相对的是下面这段 SQL 代码:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">begin</span> transaction;</span><br><span class="line"><span class="keyword">update</span> counter <span class="keyword">set</span> <span class="keyword">value</span> <span class="operator">=</span> <span class="keyword">value</span> <span class="operator">+</span> <span class="number">1</span> <span class="keyword">where</span> id <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line">if ROUND(RAND(),<span class="number">0</span>)<span class="operator">=</span><span class="number">1</span></span><br><span class="line"><span class="keyword">begin</span>;</span><br><span class="line"> THROW <span class="number">50000</span>, <span class="string">'Oops!'</span>, <span class="number">1</span></span><br><span class="line"><span class="keyword">end</span>;</span><br><span class="line"><span class="keyword">update</span> counter <span class="keyword">set</span> <span class="keyword">value</span> <span class="operator">=</span> <span class="keyword">value</span> <span class="operator">+</span> <span class="number">1</span> <span class="keyword">where</span> id <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line"><span class="keyword">commit</span>;</span><br></pre></td></tr></table></figure><br>即便没有异常出现,如果没有 Isolation(或者 Isolation.level = READ_UNCOMMMITTED),则其它事务能看到这段代码的中间状态,但如果有异常出现,第一次自增的操作会被回滚。<br>从这个角度来说,ACID 中的 Atomicity 更多的指的是在错误出现时能够自动撤销之前修改,也许把 "A" 理解成 Abortability 更恰当。</p>
<h3 id="一致性-Consistency"><a href="#一致性-Consistency" class="headerlink" title="一致性(Consistency)"></a>一致性(Consistency)</h3><p>ACID 中的一致性,表示事务只会将数据从一种“正确”的状态修改成另一种“正确”的状态。举例来说如果说有一个用户交易系统,所有的事务只会把金额从一个账户转移到另一个账户,那么可以保证的是无论执行多少次转账交易,该系统所有账户的余额都是“正确”的。<br>这里的“正确”之所以要打引号是因为它是由应用定义的,除了一些外键约束,唯一约束之外,数据库并不能理解当前的数据是否符合你对“正确”的定义。<br>换句话说,原子性,隔离性,持久性是数据库的属性,但一致性可能更应该被看成应用的属性,应用通过数据库提供的原子性,隔离性来保证数据的一致性。因此 "C" 并不真的属于 “ACID”(It was said that the C in ACID was "tossed in to make the acronym work")。</p>
<!--阅读全文-->
<p class="post-more-link">
<a href="/post/2019/05/the-good-old-transaction/#more">阅读全文</a>
</p>
</div>
<footer class="post-footer">
</footer>
</div>
</article>
<nav class="site-pagination">
<span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><span class="space">…</span><a class="page-number" href="/page/6/">6</a><a class="extend next" rel="next" href="/page/2/"><i class="fa fa-angle-right"></i></a>
</nav>
</main>
</div>
<div class="col-md-3">
<aside class="side-nav">
<aside class="widget" id="site-profile">
<img src="/img/logo_brown.png">
<h3 class="widget-title">staynoob! not stay noob!</h3>
<div class="widget-content">
<a href="https://github.com/noob9527" target="_blank">
<i class="fa fa-2x fa-github"></i>
</a>
<a href="http://weibo.com/p/1005052678297054" target="_blank">
<i class="fa fa-2x fa-weibo"></i>
</a>
<a href="/atom.xml" rel="alternate">
<i class="fa fa-2x fa-rss"></i>
</a>
</div>
</aside>
<aside class="widget" id="local-search">
<h3 class="widget-title">站内搜索</h3>
<div class="widget-content">
<label for="local-search-input" class="sr-only">search</label>
<input type="search" placeholder="search"
id="local-search-input" class="form-control">
<div id="local-search-result"></div>
</div>
</aside>
<aside class="widget">
<h3 class="widget-title">最新文章</h3>
<div class="widget-content">
<ul class="recent-posts">
<li>
<a href="/post/2024/06/notes-on-high-performance-mysql/">Notes on High Performance MySQL</a>
</li>
<li>
<a href="/post/2024/06/exploration-vs-exploitation/">Exploration vs Exploitation</a>
</li>
<li>
<a href="/post/2019/10/why-i-think-kotlin-is-preferable-to-java/">Why I think Kotlin is preferable to Java</a>
</li>
<li>
<a href="/post/2019/05/when-soft-delete-meets-unique-index/">When "Soft Delete" Meets "Unique Index"</a>
</li>
<li>
<a href="/post/2019/05/the-good-old-transaction/">The Good Old Transaction</a>
</li>
<li>
<a href="/post/2019/03/is-distributed-lock-safe/">分布式锁真的“安全”吗?</a>
</li>
<li>
<a href="/post/2019/03/strong-consistency-model/">(译)Strong Consistency Models</a>
</li>
<li>
<a href="/post/2019/02/common-pitfalls-in-jpa-hibernate/">Common Pitfalls in JPA(Hibernate)</a>
</li>
<li>
<a href="/post/2019/02/common-pitfalls-of-declarative-transaction-management-in-spring/">Common Pitfalls of Declarative Transaction Management in Spring</a>
</li>
<li>
<a href="/post/2019/01/understanding-zombie-process/">Understanding Zombie Process</a>
</li>
<li>
<a href="/post/2017/07/%E5%86%8D%E8%B0%88js%E9%97%AD%E5%8C%85/">再谈js闭包</a>
</li>
<li>
<a href="/post/2017/06/B-tree%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/">B-tree数据结构</a>
</li>
<li>
<a href="/post/2017/03/lambda-calculus-Y-combinator/">lambda calculus:Y-combinator</a>
</li>
<li>
<a href="/post/2017/03/lambda-calculus-Introduction/">lambda calculus:Introduction</a>
</li>
<li>
<a href="/post/2017/03/%E5%8A%A0%E5%AF%86%E7%AE%97%E6%B3%95%E7%AE%80%E4%BB%8B/">加密算法简介</a>
</li>
</ul>
</div>
</aside>
<aside class="widget">
<h3 class="widget-title">分类</h3>
<div class="widget-content">
<ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/Algorithm/">Algorithm</a><span class="category-list-count">6</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Backend/">Backend</a><span class="category-list-count">8</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Diary/">Diary</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Frontend/">Frontend</a><span class="category-list-count">3</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Functional-Programming/">Functional Programming</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Mathematic/">Mathematic</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Programming-Language/">Programming Language</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Security/">Security</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/System/">System</a><span class="category-list-count">3</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E6%B0%B8%E8%BF%9C%E8%AE%B0%E4%B8%8D%E4%BD%8F%E7%9A%84%E7%BC%96%E7%A8%8B%E5%A7%BF%E5%8A%BF/">永远记不住的编程姿势</a><span class="category-list-count">2</span></li></ul>
</div>
</aside>
<aside class="widget">
<h3 class="widget-title">标签</h3>
<div class="widget-content tag-cloud">
<a href="/tags/CSS/" style="font-size: 15px;">CSS</a> <a href="/tags/Database/" style="font-size: 20px;">Database</a> <a href="/tags/Distributed-System/" style="font-size: 15px;">Distributed System</a> <a href="/tags/Hibernate/" style="font-size: 10px;">Hibernate</a> <a href="/tags/JPA/" style="font-size: 20px;">JPA</a> <a href="/tags/Jackson/" style="font-size: 10px;">Jackson</a> <a href="/tags/Java/" style="font-size: 10px;">Java</a> <a href="/tags/Javascript/" style="font-size: 10px;">Javascript</a> <a href="/tags/Kotlin/" style="font-size: 10px;">Kotlin</a> <a href="/tags/Lambda-Calculus/" style="font-size: 15px;">Lambda Calculus</a> <a href="/tags/Linux/" style="font-size: 20px;">Linux</a> <a href="/tags/SQL/" style="font-size: 10px;">SQL</a> <a href="/tags/Sort/" style="font-size: 20px;">Sort</a> <a href="/tags/Spring/" style="font-size: 20px;">Spring</a> <a href="/tags/UNIX/" style="font-size: 10px;">UNIX</a> <a href="/tags/%E7%BC%96%E7%A8%8B%E6%8A%80%E5%B7%A7/" style="font-size: 15px;">编程技巧</a>
</div>
</aside>
<aside class="widget">
<h3 class="widget-title">归档</h3>
<div class="widget-content">
<ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2024/06/">June 2024</a><span class="archive-list-count">2</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/10/">October 2019</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/05/">May 2019</a><span class="archive-list-count">2</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/03/">March 2019</a><span class="archive-list-count">2</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/02/">February 2019</a><span class="archive-list-count">2</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/01/">January 2019</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/07/">July 2017</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/06/">June 2017</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/03/">March 2017</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/02/">February 2017</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/01/">January 2017</a><span class="archive-list-count">2</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/12/">December 2016</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/09/">September 2016</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/06/">June 2016</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/05/">May 2016</a><span class="archive-list-count">5</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/04/">April 2016</a><span class="archive-list-count">3</span></li></ul>
</div>
</aside>
</aside>
</div>
</div>
</div>
<footer id="footer">
<div id="footer-info">
©
2015 -
<span itemprop="copyrightYear">2024</span>
noob9527<br>
Powered by <a href="/about">xy</a>
.
Theme Noob by <a href="/about">xy</a>
</div>
</footer>
<script type="text/javascript">
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "//hm.baidu.com/hm.js?855dd1a156248c0c337788236167c870";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-76868752-1', 'auto');
ga('send', 'pageview');
</script>
<script type="text/javascript">
(function() {
var hm = document.createElement("script");
hm.src = "//tajs.qq.com/stats?sId=55612284";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<script>
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>
<!-- <script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
processEscapes: true,
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
}
});
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Queue(function() {
var all = MathJax.Hub.getAllJax(), i;
for (i=0; i < all.length; i += 1) {
all[i].SourceElement().parentNode.className += ' has-jax';
}
});
</script>
<script type="text/javascript" src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> -->
<!-- upgrade to mathjax 3 -->
<!-- see https://www.mathjax.org/#gettingstarted -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
}
};
</script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
</body>
</html>