Rumah  >  Artikel  >  pangkalan data  >  Apakah mata pengetahuan yang berkaitan dengan kunci Java dan Mysql?

Apakah mata pengetahuan yang berkaitan dengan kunci Java dan Mysql?

王林
王林ke hadapan
2023-05-27 10:18:171030semak imbas

    Definisi kunci

    Dalam program komputer, kunci digunakan untuk sumber eksklusif Hanya apabila kunci diperolehi, sumber yang sepadan boleh dikendalikan.

    Pelaksanaan kunci

    Pelaksanaan kunci di bahagian bawah komputer bergantung pada arahan CAS (bandingkan dan swsp) yang disediakan oleh CPU Untuk alamat memori, nilai asal dan nilai yang cuba diubah suai akan dibandingkan , menunjukkan sama ada kunci telah dirampas sama ada nilai itu berjaya diubah suai.

    Kunci dalam JVM

    Dalam jvm, terdapat 2 kunci yang biasa digunakan

    disegerakkan

    disegerakkan ialah kunci kata kunci yang disediakan oleh java, yang boleh mengunci objek , kelas, kaedah.
    Selepas JDK1.6, disegerakkan telah dioptimumkan dan kunci berat sebelah dan mod kunci ringan telah ditambah Sekarang logik pengendalian kunci disegerakkan adalah seperti berikut:

    • Apabila mengunci pada mulanya. akan menambah kunci berat sebelah, iaitu, "berat sebelah pada benang yang terakhir memperoleh kunci ". Mod ini meningkatkan daya pemprosesan satu utas yang berulang kali memperoleh kunci yang sama Menurut pegawai Java, kebanyakan pertikaian kunci berlaku pada utas yang sama.

    • Jika pemerolehan CAS kunci berat sebelah gagal, ini bermakna utas semasa adalah berbeza daripada utas yang dipincang oleh kunci pincang dan kunci pincang akan dinaik taraf kepada kunci ringan, iaitu kunci ringan Cirinya adalah untuk mendapatkan kunci melalui putaran CAS .

    • Jika pemerolehan putaran gagal, kunci akan dinaik taraf kepada kunci berat, dan semua benang yang menunggu kunci akan digantung oleh JVM Selepas kunci dilepaskan, ia akan dikejutkan oleh pemberitahuan bersatu daripada JVM Cuba kunci CAS sekali lagi.

    Jelas sekali, tujuan reka bentuk kunci berat sebelah ialah "dari perspektif Java rasmi, kebanyakan pertikaian untuk kunci yang sama berlaku pada urutan yang sama."
    Tujuan reka bentuk kunci ringan ialah "dalam jangka pendek, pertikaian kunci boleh diperoleh melalui putaran CAS, dan penggunaan putaran CPU dalam tempoh yang singkat adalah kurang daripada penggunaan penggantungan benang dan bangun semula."
    Kunci berat ialah logik yang disegerakkan sebelum pengoptimuman awal.

    ReentrantLock

    Bercakap tentang ReentrantLock, kita perlu bercakap tentang AQS dalam JUC.
    Nama penuh AQS ialah AbstractQueueSynchronizer Hampir semua kelas alat dalam JUC bergantung pada AQS untuk pelaksanaan.
    AQS ialah kelas abstrak dalam java, tetapi pada asasnya ia adalah pelaksanaan idea dalam java.
    Logik pelaksanaan AQS adalah seperti berikut:

    • Bina baris gilir

    • Baris gilir mengekalkan benang yang perlu menunggu kunci

    • Nod kepala sentiasa nod yang memegang kunci (atau memegang sumber), dan nod menunggu disambungkan mengikut urutan selepas nod kepala.

    • Selepas nod kepala melepaskan kunci, ia akan membangunkan nod menunggu mengikut tertib, dan kemudian nod tersebut akan cuba memperoleh kunci itu semula.

    Selepas pengoptimuman kunci yang disegerakkan, intipati AQS tidak jauh berbeza daripada yang disegerakkan, dan tidak terdapat banyak perbezaan dalam prestasi antara keduanya, jadi ciri-ciri semasa AQS adalah:

    • ialah kunci yang dilaksanakan pada peringkat java api, jadi ia boleh melaksanakan pelbagai kelas alat serentak dan operasinya lebih fleksibel

    • kerana ia menyediakan tamat masa, dsb. Mekanisme ini fleksibel dalam operasi, jadi tidak mudah untuk menemui jalan buntu. Jika kebuntuan berlaku, ia akan menjadi lebih sukar untuk menyelesaikan masalah kerana jstack tidak akan menunjukkan penunjuk jalan buntu.

    • boleh mencapai kunci yang adil, tetapi yang disegerakkan mestilah kunci yang tidak adil.

    • Oleh kerana ia adalah kunci yang dilaksanakan oleh lapisan JavaApi, ia boleh bertindak balas terhadap gangguan.

    Di sini anda akan mendapati bahawa ReentrantLock sebenarnya boleh dikatakan sebagai pelaksanaan yang disegerakkan pada lapisan JavaApi.

    Kunci Mysql

    Kunci kongsi (S) dan kunci eksklusif (X)

    Skop

    Kedua-dua kunci ini termasuk kunci peringkat baris dan Aras meja kunci.
    Apabila memperoleh kunci kongsi, jika data dikunci oleh kunci eksklusif transaksi lain, ia tidak boleh diperoleh dan perlu menunggu kunci eksklusif dikeluarkan.

    Kunci niat

    Skop

    Kunci niat ialah kunci mejaSebelum memperoleh kunci meja, kunci niat akan diperiksa.

    Protokol penguncian niat adalah seperti berikut:

    Sebelum transaksi boleh mendapatkan kunci kongsi pada baris dalam jadual, ia mesti mendapatkan kunci IS terlebih dahulu atau kunci yang lebih kuat di atas meja.

    Sebelum transaksi boleh mendapatkan kunci eksklusif pada baris dalam jadual, ia mesti mendapatkan kunci IX di atas meja terlebih dahulu.

    Sebelum memperoleh kunci kongsi atau eksklusif pada mana-mana kunci meja, kunci kongsi pada meja mesti diperiksa.

    Peraturan pengecualian bersama untuk kunci meja dan kunci niat adalah seperti berikut:
    X IX S IS
    >IS Konflik Serasi Serasi Serasi


    Tujuan niat kunci ialah: apabila memperoleh kunci meja, anda boleh menggunakan kunci niat untuk menentukan dengan cepat sama ada ia boleh diperoleh.

    Oleh kerana apabila memperoleh kunci peringkat baris, kunci niat yang sepadan akan diperoleh terlebih dahulu, supaya transaksi lain boleh menilai dengan cepat melalui kunci niat apabila memperoleh kunci meja, tanpa mengimbas setiap baris.

    Perhatian khusus ialah kunci niat boleh ditindih, iaitu, akan ada berbilang. Contohnya, transaksi T1 memperoleh kunci niat IX1 dan kunci peringkat baris X1, dan transaksi T2 masih boleh. memperoleh kunci niat IX2 dan kunci peringkat baris X2, jadi kunci niat diperiksa hanya sebelum kunci peringkat meja diperoleh.

    Kunci rekod

    Kunci rekod berkuat kuasa pada indeks untuk melindungi data baris daripada ditukar oleh transaksi lain apabila PILIH c1 DARI t DI MANA c1 = 10 UNTUK KEMASKINI.

    Penguncian rekod masih akan berkuat kuasa apabila tiada indeks, kerana innodb akan mencipta indeks tersembunyi untuk setiap jadual.

    Kunci rekod ialah kunci baris yang paling asas.

    Kunci celah

    Kunci celah berkuat kuasa pada indeks dan digunakan untuk mengunci baris selepas nilai indeks untuk mengelakkan sisipan. Ia akan berkuat kuasa apabila memilih daripada jadual di mana index= untuk kemas kini , seperti index= 1, baris yang berkaitan dengan nod indeks dengan index=1 akan dikunci untuk menghalang transaksi lain daripada memasukkan data.

    Tetapi ia tidak akan menghalang kenyataan kemas kini, walaupun data kemas kini tidak wujud.

    Kunci Kekunci Seterusnya

    Kunci ini ialah gabungan kunci rekod dan kunci celah Secara ringkasnya, apabila memilih daripada jadual di mana index= untuk kemas kini, akan ada jurang Kunci menghalang sisipan, dan terdapat juga kunci rekod pada indeks untuk menghalang kemas kini dan memadam sekeping data ini. Kunci Seterusnya ini hanyalah generalisasi bagi kedua-dua kunci ini, kerana kedua-dua kunci ini biasanya muncul bersama apabila memilih untuk kemas kini.

    Masukkan Kunci Niat

    Masukkan kunci niat, serupa dengan kunci niat. Ia adalah kunci jurang khas, yang tidak berlaku dalam pilih untuk kemas kini, tetapi berlaku apabila sisipan berlaku pada masa yang sama Contohnya, apabila dua transaksi memasukkan julat indeks [4,7] pada masa yang sama, mereka memperoleh niat kunci julat pada masa yang sama Ini Apabila transaksi disekat, contohnya, A: masukkan-5, B: masukkan-7, kedua-dua transaksi tidak akan disekat pada masa ini.

    Kunci niat sisipan ialah kunci celah khas, yang direka untuk mengelakkan penyekatan yang kerap pada sisipan dalam kes selang kunci celah biasa, seperti A: sisipan-5, B: sisipan-7, jika tidak Masukkan kunci niat, maka kedua-dua 5 dan 7 akan cuba memperoleh kunci jurang Pada masa ini, transaksi kedua akan disekat Namun, dengan memasukkan kunci niat, transaksi kedua tidak akan disekat, dan hanya yang dimasukkan baris memang akan bercanggah , akan disekat.

    Kunci AUTO-INC

    Kunci kenaikan automatik, kunci ini jelas merupakan kunci sisipan peringkat jadual, untuk memastikan kunci utama jadual dengan kunci utama kenaikan automatik dikekalkan kenaikan auto atom.

    Bagi kunci, semua orang harus memahami lebih lanjut tentang prinsip dan model pelbagai reka bentuk dan operasi kunci, supaya selepas mendalami pemahaman mereka, mereka boleh menggunakannya dengan lebih mendalam dan teliti.

    Senario dan penggunaan penguncian biasa

    semakan berganda

    Seperti yang kita sedia maklum, urus niaga mysql tidak berguna dalam menghalang sisipan berulang, dan indeks unik mempunyai banyak kelemahan Adalah lebih baik untuk tidak menggunakannya, secara amnya, cara biasa untuk mengelakkan pemasukan berulang adalah dengan menggunakan kunci teragih Ini adalah cara penulisan yang lebih biasa digunakan.

    final WeekendNoticeReadCountDO weekendNoticeReadCountDO = weekendNoticeReadRepositoryService.selectByNoticeId(noticeRequestDTO.getNoticeId());
    if (weekendNoticeReadCountDO == null) {
        final String lockKey = RedisConstant.LOCK_WEEKEND_READ_COUNT_INSERT + ":" + noticeRequestDTO.getNoticeId();
        ClusterLock lock = clusterLockFactory.getClusterLockRedis(
            RedisConstant.REDIS_KEY_PREFIX,
            lockKey
        );
        if (lock.acquire(RedisConstant.REDIS_LOCK_DEFAULT_TIMEOUT)) {
            //double check
            final WeekendNoticeReadCountDO weekendNoticeReadCountDO = weekendNoticeReadRepositoryService.selectByNoticeId(noticeRequestDTO.getNoticeId());
            if (weekendNoticeReadCountDO == null) {
                try {
                    lock.execute(() -> {
                        WeekendNoticeReadCountDO readCountDO = new WeekendNoticeReadCountDO();
                        readCountDO.setNoticeId(noticeRequestDTO.getNoticeId());
                        readCountDO.setReadCount(1L);
                        readCountDO.setCreateTime(new Date());
                        readCountDO.setUpdateTime(new Date());
                        weekendNoticeReadRepositoryService.insert(readCountDO);
                        return true;
                    });
                } catch (ApiException err) {
                    throw err;
                } catch (Exception e) {
                    log.error("插入", e);
                    throw new ApiException(ErrorEnum.SERVER_ERROR.getCode(), "服务端出错");
                }
            } else {
                weekendNoticeReadRepositoryService.noticeCountAdd(weekendNoticeReadCountDO);
            }
        } else {
            log.warn("redis锁获取超时,key:{}", lockKey);
            throw new ApiException(ErrorEnum.SERVER_ERROR.getCode(), "服务器繁忙,请稍后重试");
        }
    }

    Selepas memperoleh kunci, ia mungkin diperoleh selepas menunggu Pada masa ini, urutan sebelumnya yang mengeluarkan kunci mungkin telah memasukkan data, jadi di dalam kunci, data masih perlu disahkan semula .
    Kaedah penulisan ini sesuai untuk kebanyakan senario penulisan yang memerlukan keunikan.

    Elak kebuntuan

    Bagaimana untuk mengelakkan kebuntuan? Kaedah yang paling mudah dan berkesan ialah: **Jangan masukkan kunci di dalam kunci Secara ringkasnya, sebaiknya gunakan kunci sahaja, bukan sebagai anak patung bersarang.
    Juga perhatikan beberapa kunci tersirat, seperti pangkalan data.
    Transaksi A:

    • Masukkan [5,7] dan masukkan kunci niat.

    • pilih untuk kemas kini kemas kini [100,150], kunci jurang.
      Transaksi B:

    • pilih untuk kemas kini [90,120], kunci jurang.

    • Masukkan [4,6] dan masukkan kunci niat.

    Pada masa ini, dalam senario serentak, mungkin berlaku bahawa A memegang kunci jurang [5,7] dan sedang menunggu kunci jurang transaksi B[90,120]. Transaksi B juga Sama, ia buntu.
    **

    Dengan cara ini, mari kita bincangkan tentang masalah biasa dalam senario bersamaan

    Kekeliruan dalam membaca dan menulis

    Apabila menulis kod perniagaan dan menentukan beberapa kelas alat atau kelas cache, Ia adalah mudah untuk cuai dan menyebabkan masalah yang sama.
    Sebagai contoh, semasa membina cache statik, kaedah seperti putIfAbsent dalam ConcurrentHashMap tidak digunakan dan tiada kunci digunakan untuk membinanya Akibatnya, utas di bawah dipadamkan sebaik sahaja urutan di atas meletakkannya, atau cache dibina dua kali.

    Redis atau beberapa operasi serentak mengeluarkan kunci atau sumber tanpa memeriksa sama ada utas semasa memegangnya

    Ini juga disebut dalam kod contoh kunci Redis.
    Benang A memperoleh kunci Pada masa ini, B dan C sedang menunggu Kemudian masa pelaksanaan A terlalu lama, menyebabkan kunci dilepaskan secara automatik Pada masa ini, B memperoleh kunci dan melaksanakan Dengan gembiranya selepas A selesai melaksanakan, Apabila melepaskan kunci, ia tidak dinilai sama ada ia masih dipegang dengan sendirinya, menyebabkan kunci yang dipegang oleh B dipadamkan Pada masa ini, C memperoleh kunci itu semula, dan BC telah dilaksanakan pada masa yang sama.

    Atas ialah kandungan terperinci Apakah mata pengetahuan yang berkaitan dengan kunci Java dan Mysql?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Kenyataan:
    Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam