数据库
首页 > 数据库> > 学习Mysql第4天(触发器、事务)

学习Mysql第4天(触发器、事务)

作者:互联网

1 Trigger触发器

TRIGGER 是在插入、更新、删除语句前后自动执行的一段sql语句,分为INSERT/update/delete

DROP TRIGGER IF EXISTS PAYMENTS_AFTER_INSERT;

DELIMITER $$
CREATE TRIGGER PAYMENTS_AFTER_INSERT
	AFTER INSERT ON PAYMENTS  -- 触发器可以修改任何表数据,但不能修改所在表,即这个。
    FOR EACH ROW
BEGIN
	UPDATE INVOICES I
	SET PAYMENT_TOTAL  =  PAYMENT_TOTAL + NEW.AMOUNT
    WHERE I.INVOICE_ID = NEW.INVOICE_ID;
    
    INSERT INTO PAYMENTS_AUDIT  -- 加入审计表中
    VALUES (NEW.CLIENT_ID,NEW.DATE,NEW.AMOUNT,'INSERT',NOW());
END $$

DELIMITER ;
SET SQL_SAFE_UPDATES=0;   -- 关闭更新的安全模式

INSERT INTO PAYMENTS
VALUES (DEFAULT,5,3,'2019-01-01',10,1);

-- delete审计
	-- 创建trigger
DROP TRIGGER IF EXISTS PAYMENTS_AFTER_DELETE;

DELIMITER $$
CREATE TRIGGER PAYMENTS_AFTER_DELETE
	AFTER DELETE ON PAYMENTS  -- 触发器可以修改任何表数据,但不能修改所在表,即这个。
    FOR EACH ROW
BEGIN
	UPDATE INVOICES I
	SET PAYMENT_TOTAL  =  PAYMENT_TOTAL - OLD.AMOUNT
    WHERE I.INVOICE_ID = OLD.INVOICE_ID;
    
    INSERT INTO PAYMENTS_AUDIT  -- 加入审计表中
    VALUES (OLD.CLIENT_ID, OLD.DATE, OLD.AMOUNT, 'DELETE', NOW());
END $$
DELIMITER ;
	-- 执行delete审计
DELETE 
FROM PAYMENTS
WHERE PAYMENT_ID = 13;
SHOW TRIGGERS LIKE 'PAYMENT%';

2 Event 事件

可以自动执行的一段sql,自动化数据库维护

SHOW VARIABLES LIKE 'EVENT%';  -- 查看sql变量
SET GLOBAL EVENT_SCHEDULER = 'ON';  -- 打开

-- 创建一个event
DELIMITER $$
CREATE EVENT HOUSLY_DELETE_AUDIT_ROWS
ON SCHEDULE
	EVERY 1 HOUR STARTS '2021-06-01' ENDS '2021-07-01'
DO BEGIN 
	DELETE FROM PAYMENT_AUDIT
    WHERE ACTION_DATE < NOW();
END $$
DELIMITER ;

-- SHOW
SHOW EVENTS;
DROP EVENT IF EXISTS HOUSLY_DELETE_AUDIT_ROWS;
ALTER EVENT HOUSLY_DELETE_AUDIT_ROWS DISABLE -- 关闭event

3 TRANSACTION 事务

使用事务处理(transaction processing),通过确保成批的SQL操作要么完全执行,要么完全不执行,来维护数据库的完整性。

USE SQL_STORE;

START TRANSACTION;

INSERT INTO ORDERS (CUSTOMER_ID, ORDER_DATE, STATUS )
VALUES (1,'2019-01-01',1);

INSERT INTO ORDER_ITEMS
VALUES (last_insert_id(),1,1,1);

COMMIT;  -- rollback

并发与锁定 并发:多个用户同时访问同一个数据,因此当用户改变数据时,就有问题

– MYSQL默认机制是,当两个以上用户同时修改统一数据时,会按照提交的先后顺序进行修改。

USE SQL_STORE;

START TRANSACTION;

UPDATE CUSTOMERS
SET POINTS = pointS+10
WHERE CUSTOMER_ID = 1;
COMMIT; 

– 常见的并发问题

  1. dirty read
    通过加入限制来解决。让只读已提交的数据。

    例如:user1给了客户a20积分,但没有提交,此时user2查看客户积分进行打折.如果user1进行rollbac,即user2拿到了不属于客户的积分数据,未提交的数据,由此是dirty data.

  2. non-repeating
    可以加入事务隔离级别,即使其他用户修改了数据,也使得数据和最开始读取的数据一致.

    例如:user1 读取客户数据积分a(未提交),user2修改了客户积分b,user1再次读取客户积分b,由此产生数据不一样。

  3. phantom read 幻读
    可以设置事务隔离级别,按照先后顺序。

    例如:事务A读取客户积分,事务B修改了一个客户的积分,且未返回,事务A查询的就会发生变化,无法在查询中看到。—

4个隔离级别

 读未提交 -> 读已提交 -> 可重复读取 -> 可序化  、

针对以上三个并发问题,采用2,3,4等级即可解决。

– 随着限制级越高,所需要计算资源也就越大,但可以解决的并发问题就越多。综合起来优先选择repeated read第三级。
– 查看当前隔离级别

SHOW VARIABLES LIKE 'TRANSACTION%'

– 读未提交级别 read uncommitted / read committed / read repeat /

标签:AUDIT,INSERT,触发器,--,事务,PAYMENTS,Mysql,ID,DELETE
来源: https://blog.csdn.net/weixin_42327752/article/details/118085022