Ini mungkin logika bisnis, yang mungkin tidak termasuk dalam lapisan penyimpanan data Anda. Namun, hal itu tetap dapat dilakukan dengan menggunakan pemicu .
Anda dapat membuat BEFORE UPDATE
pemicu yang menimbulkan kesalahan jika catatan "terkunci" akan diperbarui; karena kesalahan terjadi sebelum operasi dilakukan, MySQL berhenti untuk melanjutkannya. Jika Anda juga ingin mencegah catatan dihapus, Anda harus membuat pemicu serupa BEFORE DELETE
.
Untuk menentukan apakah suatu record "dikunci", Anda dapat membuat boolean locked
kolom:
ALTER TABLE my_table ADD COLUMN locked BOOLEAN NOT NULL DEFAULT FALSE;
DELIMITER ;;
CREATE TRIGGER foo_upd BEFORE UPDATE ON my_table FOR EACH ROW
IF OLD.locked THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot update locked record';
END IF;;
CREATE TRIGGER foo_del BEFORE DELETE ON my_table FOR EACH ROW
IF OLD.locked THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot delete locked record';
END IF;;
DELIMITER ;
UPDATE my_table SET locked = TRUE WHERE ...;
Perhatikan bahwa SIGNAL
diperkenalkan di MySQL 5.5. Di versi sebelumnya, Anda harus melakukan beberapa tindakan salah yang menyebabkan MySQL memunculkan kesalahan:Saya sering memanggil prosedur yang tidak ada, mis. dengan CALL raise_error;
Sekali lagi, jika Anda benar-benar harus menempatkan logika ini di lapisan penyimpanan—dan tidak dapat mengidentifikasi catatan yang dikunci melalui cara apa pun selain PK—Anda bisa hard-code tes ke pemicu Anda; misalnya, untuk "mengunci" catatan dengan id_column = 1234
:
DELIMITER ;;
CREATE TRIGGER foo_upd BEFORE UPDATE ON my_table FOR EACH ROW
IF OLD.id_column <=> 1234 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot update locked record';
END IF;;
CREATE TRIGGER foo_del BEFORE DELETE ON my_table FOR EACH ROW
IF OLD.id_column <=> 1234 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot delete locked record';
END IF;;
DELIMITER ;
Tapi ini benar-benar mengerikan dan saya akan melakukan hampir semua untuk menghindarinya bila memungkinkan.